Saltar al contenido
ecdsa.com
Node.js tls / https / fetchcrypto de Node.js

Mensaje de error

unable to get local issuer certificate

También se muestra como

  • code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY'
  • UNABLE_TO_GET_ISSUER_CERT_LOCALLY

Con fetch(), el mensaje es la causa de «TypeError: fetch failed»; npm notifica la misma situación como «npm error code UNABLE_TO_GET_ISSUER_CERT_LOCALLY». Si el servidor envía solo su certificado hoja, Node.js notifica en su lugar «unable to verify the first certificate».

Node.js tls / https / fetch — code UNABLE_TO_GET_ISSUER_CERT_LOCALLY (OpenSSL X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, 20)

Qué significa

El servidor envió una cadena (hoja e intermedio), pero el certificado de su extremo superior lo emitió una raíz en la que Node.js no confía. De forma predeterminada, Node.js solo confía en la lista de raíces de Mozilla compilada dentro del binario, no en el almacén del sistema operativo, así que una raíz de la empresa instalada en el equipo le resulta invisible a menos que le indiques que la use.

Por qué ocurre

Cómo solucionarlo

  1. 1.

    NODE_EXTRA_CA_CERTS

    Indica a Node.js un archivo PEM cuyos certificados se añaden a las raíces integradas. La variable se lee una sola vez, al arrancar el proceso, así que exportarla dentro de una aplicación en ejecución no tiene efecto.

    bash
    # Adds to Node's built-in roots; read once at start-up, so set it before node starts
    export NODE_EXTRA_CA_CERTS=/etc/ssl/private-ca/corp-root-ca.pem
    node app.js
  2. 2.

    Usar el almacén del sistema operativo

    --use-system-ca (o NODE_USE_SYSTEM_CA=1 en el entorno) hace que Node.js confíe en los certificados en los que confía el sistema operativo, que son los que gestionan los departamentos de TI.

    bash
    # Trust what the operating system trusts (Windows store, macOS Keychain, Linux bundle)
    node --use-system-ca app.js
    # or, for tools that start node themselves (npm scripts, CLIs):
    NODE_USE_SYSTEM_CA=1 npx some-cli
  3. 3.

    Establecer la lista de CA predeterminada en el código

    tls.setDefaultCACertificates() sustituye la lista predeterminada para las conexiones posteriores de https, tls y fetch; combina los certificados predeterminados actuales con tu raíz, como se muestra.

    js
    // In code, before the first request: keep the default roots and add yours.
    // Applies to https, tls and fetch. Available in current Node.js 22 and 24 releases.
    import tls from "node:tls";
    import fs from "node:fs";
    
    tls.setDefaultCACertificates([
      ...tls.getCACertificates("default"),
      fs.readFileSync("/etc/ssl/private-ca/corp-root-ca.pem", "utf8"),
    ]);
  4. 4.

    Confiar en la raíz para un solo agente

    La opción ca de un agente o de tls.connect() sustituye las raíces predeterminadas en esas conexiones, así que incluye tls.rootCertificates si el mismo agente también se comunica con hosts públicos.

    js
    // Per-agent trust: note that "ca" REPLACES the default roots, so append them
    import https from "node:https";
    import tls from "node:tls";
    import fs from "node:fs";
    
    const agent = new https.Agent({ ca: [...tls.rootCertificates, fs.readFileSync("corp-root-ca.pem", "utf8")] });
    https.get("https://api.example.com/", { agent }, (res) => res.resume());

Errores relacionados

Explorar toda la base de datos de errores de firma