本文へスキップ
ecdsa.com
Node.js tls / https / fetchNode.js の crypto

エラーメッセージ

certificate has expired

別の表記

  • code: 'CERT_HAS_EXPIRED'
  • CERT_HAS_EXPIRED

メッセージのテキストはすべての Node.js のバージョンで同じです。fetch() では「TypeError: fetch failed」の原因として現れ、npm は「npm error code CERT_HAS_EXPIRED」と出力します。まだ有効ではない証明書の場合は、代わりに CERT_NOT_YET_VALID になります。

Node.js tls / https / fetch — code CERT_HAS_EXPIRED (OpenSSL X509_V_ERR_CERT_HAS_EXPIRED, 10)

このエラーの意味

Node.js が構築したチェーン内のいずれかの証明書が、このマシンの時計で見て notAfter の日付を過ぎています。通常はサーバー自身の証明書ですが、サーバーがまだ送信している中間証明書や、古い Node.js のリリースに同梱された、更新されていないルートリストに含まれるルートである場合もあります。Node.js はこれを「certificate has expired」というメッセージとコード CERT_HAS_EXPIRED で報告します。

発生する理由

修正方法

  1. 1.

    返される証明書の日付を確認する

    証明書を読み取るためだけに、検証なしで一度だけ接続してください。valid_to と authorizationError を見れば、どの証明書が期限切れかがわかります。その接続ではデータを送信しないでください。

    js
    // Read the dates of the served certificate (inspection only, nothing is sent)
    import tls from "node:tls";
    
    const socket = tls.connect({ host: "api.example.com", port: 443, servername: "api.example.com", rejectUnauthorized: false }, () => {
      const cert = socket.getPeerCertificate();
      console.log(cert.subject.CN, cert.valid_from, "->", cert.valid_to, "authorized:", socket.authorized, socket.authorizationError);
      socket.end();
    });
  2. 2.

    サーバー証明書を更新してリロードする

    ACME クライアントまたは CA を通じて更新し、TLS を終端するすべてのプロセスをリロードしてから、ネットワーク側から新しい有効期限を確認してください。

    bash
    sudo certbot renew && sudo systemctl reload nginx
    echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null | openssl x509 -noout -enddate
  3. 3.

    古い環境の Node.js をアップグレードする

    ほかのクライアントではサーバーの証明書が有効と判定される場合は、Node.js の古いルートリストが原因である可能性が高いです。サポートが継続しているリリースにアップグレードすると、同梱のルートが更新されます。

    bash
    # Node.js bundles its root list: old releases carry old (or expired) roots
    node -v
    node -p "require('tls').rootCertificates.length"

関連するエラー

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