本文へスキップ
ecdsa.com
Node.js tls.connect / fetch (undici)Node.js の crypto

エラーメッセージ

code: 'ERR_SSL_WRONG_VERSION_NUMBER'

別の表記

  • ERR_SSL_WRONG_VERSION_NUMBER

完全なメッセージには、スレッド ID とソースのパスが含まれます(例:「60747095FFFF0000:error:0A00010B:SSL routines:tls_validate_record_header:wrong version number:../deps/openssl/openssl/ssl/record/methods/tlsany_meth.c:77:」)。そのため、コードで検索してください。tls.connect() と fetch() はコード ERR_SSL_WRONG_VERSION_NUMBER を設定し、https.request() は同じ理由を「write EPROTO …」としてコード EPROTO で報告します。

Node.js tls.connect / fetch (undici) — OpenSSL SSL_R_WRONG_VERSION_NUMBER; https.request reports it as write EPROTO

このエラーの意味

Node.js は TLS ハンドシェイクを開始しましたが、応答が TLS レコードではなかったため、OpenSSL がレコードヘッダーの検証中に失敗しました。相手はそのポートで平文で通信しています。HTTP サーバー、平文の HTTP を想定しているプロキシ、STARTTLS の前の SMTP サーバーなどです。名前とは裏腹に、証明書や TLS のバージョンには何も問題はありません。

発生する理由

修正方法

  1. 1.

    ポートがどのプロトコルで応答するかを確認する

    http:// でそのポートに問い合わせてください。応答があれば、http:// を使うか、本来の TLS ポートを使ってください。

    bash
    curl -si http://127.0.0.1:8080/ | head -1          # HTTP answers: use http:// or the TLS port
    openssl s_client -connect 127.0.0.1:8443 -brief </dev/null
  2. 2.

    プロキシの URL は http:// で書く

    プロキシ URL のスキームが表すのは、宛先への接続ではなく、プロキシへの接続です。HTTPS の宛先には、トンネルを通じて引き続きエンドツーエンドの TLS が使われます。

    bash
    # Proxy URLs for HTTPS traffic normally start with http:// (CONNECT tunnel)
    export HTTPS_PROXY=http://proxy.example.net:3128
    npm config set https-proxy http://proxy.example.net:3128
  3. 3.

    メール:587 では STARTTLS、465 では暗黙的 TLS を使う

    nodemailer では、secure: true はポート 465 用です。587 では secure: false のままにして、STARTTLS を必須にしてください。

    js
    // SMTP: secure: true only for implicit TLS (465); 587 upgrades with STARTTLS
    import nodemailer from "nodemailer";
    
    const transport = nodemailer.createTransport({ host: "smtp.example.com", port: 587, secure: false, requireTLS: true });

関連するエラー

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