Skip to content
ecdsa.com
Node.js tls / https / fetchNode.js crypto

Error message

code: 'DEPTH_ZERO_SELF_SIGNED_CERT'

Also printed as

  • self-signed certificate; if the root CA is installed locally, try running Node.js with --use-system-ca
  • DEPTH_ZERO_SELF_SIGNED_CERT

Node.js 24.22 prints the message as "self-signed certificate; if the root CA is installed locally, try running Node.js with --use-system-ca"; older releases print just "self-signed certificate" ("self signed certificate" before Node.js 17). The code is the stable part to search for.

Node.js tls / https / fetch — error.message "self-signed certificate" (OpenSSL X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, 18)

What it means

The server's certificate is self-signed (it is its own issuer, "depth zero" of the chain) and it is not in Node.js's trusted set. Node.js reports it with the message "self-signed certificate" and the code DEPTH_ZERO_SELF_SIGNED_CERT. Typical for local development servers, internal tools and services that still use the certificate generated at installation.

Why it happens

How to fix it

  1. 1.

    Trust this one certificate for one agent

    Pass the server's certificate as ca. Only this certificate is accepted, hostname and validity checks stay on; note that ca replaces the default roots for this agent.

    js
    // Trust exactly this certificate for this agent (hostname and dates are still checked)
    import https from "node:https";
    import fs from "node:fs";
    
    const agent = new https.Agent({ ca: fs.readFileSync("localhost.pem") });
    https.get("https://localhost:8443/", { agent }, (res) => res.resume());
  2. 2.

    Add the certificate for the whole process

    NODE_EXTRA_CA_CERTS works for https, tls and fetch() alike and does not require code changes.

    bash
    # Whole process, including fetch(): add the certificate to the trusted set
    NODE_EXTRA_CA_CERTS=./localhost.pem node app.js
  3. 3.

    Use a local CA for development

    A local root trusted once (mkcert, step-ca) issues properly signed certificates for every dev host and avoids per-certificate exceptions.

    bash
    # Development: a local CA (mkcert) instead of one-off self-signed certificates
    mkcert -install && mkcert localhost 127.0.0.1
    NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem" node app.js
  4. 4.

    Temporary diagnostic: rejectUnauthorized: false

    Accepts any certificate on that agent, including an attacker's. Acceptable only for a quick local check; never in code that ships.

    js
    // Temporary diagnostic in a test only: accepts ANY certificate on this agent
    const agent = new https.Agent({ rejectUnauthorized: false });

Related errors

Browse the full signature error database