本文へスキップ
ecdsa.com
npm (Node.js)パッケージマネージャー

エラーメッセージ

npm error code UNABLE_TO_VERIFY_LEAF_SIGNATURE

別の表記

  • npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE
  • npm error request to https://registry.example.com/lodash failed, reason: unable to verify the first certificate

npm 10 以降は「npm error code UNABLE_TO_VERIFY_LEAF_SIGNATURE」、npm 9 以前は「npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE」と出力します。最近の Node.js のバージョンでは、理由の行に「; if the root CA is installed locally, try running Node.js with --use-system-ca」が追加されます。

npm (Node.js) — registry request over HTTPS

このエラーの意味

レジストリ(またはその前段にあるプロキシ)が自身の証明書だけを送信し、Node.js はそれを発行した証明書を見つけられませんでした。発行者がなければ、リーフ証明書の署名はまったく検証できません。これはサーバーの設定の問題です。ハンドシェイクに中間証明書が含まれておらず、Node.js はそれをダウンロードして補うことはしません。

発生する理由

修正方法

  1. 1.

    ハンドシェイク内の証明書の数を確認する

    depth 0 しか表示されず、その発行者が中間証明書であれば、中間証明書の欠落が確定します。

    bash
    openssl s_client -connect registry.example.com:443 -servername registry.example.com -showcerts </dev/null 2>/dev/null \
      | grep -E '^ *[0-9]+ s:|^ *i:'
  2. 2.

    レジストリで完全なチェーンを返す

    レジストリの前段で TLS を終端するサーバーに、リーフ証明書と中間証明書を設定してください。これで npm、yarn、pnpm、Docker をはじめ、すべてのクライアントが一度に直ります。

    text
    # Registry behind nginx: serve leaf + intermediate(s)
    ssl_certificate     /etc/nginx/tls/registry.example.com.fullchain.pem;
    ssl_certificate_key /etc/nginx/tls/registry.example.com.key;
  3. 3.

    回避策:クライアント側で中間証明書を信頼する

    中間証明書とそのルートを含む cafile を使えば、サーバーが修正されるまでの間、npm はリーフ証明書を検証できます。cafile は npm のデフォルトのルートを置き換えるため、同じ npm で registry.npmjs.org も使う場合は、パブリックルートも追加してください。

    bash
    # Until the registry is fixed: trust the intermediate (plus its root) on the client
    cat issuing-ca.pem corp-root-ca.pem > /etc/ssl/private-ca/registry-ca.pem
    npm config set cafile /etc/ssl/private-ca/registry-ca.pem

関連するエラー

署名エラーデータベースをすべて見る