エラーメッセージ
error:0480006C:PEM routines::no start line
Node 26(OpenSSL 3.5)の X509Certificate と tls.createSecureContext() で再現を確認しています。OpenSSL 1.1.1 は同じ失敗を「error:0909006C:PEM routines:get_name:no start line」、OpenSSL 1.1.0 は「error:0906D06C:PEM routines:PEM_read_bio:no start line」と出力します。関連するエラーとして、END マーカーが壊れている場合の「error:04800066:PEM routines::bad end line」があります。
OpenSSL 3.x — also surfaces in Node as ERR_OSSL_PEM_NO_START_LINE
このエラーの意味
PEM パーサーは、想定するオブジェクトに対応する「-----BEGIN ...-----」行を入力の中から探しましたが、見つけられませんでした。ファイルがそもそも PEM ではない(バイナリの DER、JSON、空のファイル)か、BEGIN のラベルがパーサーの求めるものとは別のオブジェクトを示しているか、受け渡しの途中で PEM のフレーミングが壊れたかのいずれかです。
発生する理由
PEM パーサーに DER(バイナリ)データを渡している
よくある.der/.cer/.pfx ファイルはバイナリなので、そもそも BEGIN 行を含みません。PEM しか読み込まないローダー(証明書を読み込む tls.createSecureContext()、OpenSSL 1.1 のコマンドライン)では、まさにこのエラーになります。(Node の X509Certificate や OpenSSL 3 のコマンドは、DER を自動的に判別します。)
ラベルの不一致:ファイルは正しいがオブジェクトが違う
よくあるパーサーは、自分が扱うラベルを探します。証明書を読み込むコードは「-----BEGIN PRIVATE KEY-----」のブロックを丸ごと読み飛ばし、「no start line」を報告します。CERTIFICATE の開始行は存在しないので、技術的には正しい報告です。
受け渡しの途中でフレーミングが壊れた
よくある環境変数や JSON から来た文字としての \n や、文書エディターから貼り付けた見た目の似たダッシュがあると、BEGIN 行と一致しなくなります。最初のダッシュの前にある UTF-8 の BOM は OpenSSL 1.1 では問題になります(OpenSSL 3 と Node は読み飛ばします)。Windows の CRLF の改行や、末尾の改行の欠落は許容されます。
修正方法
- 1.
先頭のバイトを確認する
xxd の出力 1 行で、PEM(ASCII のダッシュ)、DER(先頭バイトが 0x30)、意味のないデータを区別できます。そのうえで、状況に応じて変換または修正してください。
bash head -c 32 file | xxd # 2d 2d 2d 2d 2d ("-----") → PEM: check the label matches what the tool expects # 30 82 ... → DER: add -inform der or convert: openssl x509 -inform der -in cert.der -out cert.pem - 2.
受け渡しの途中で壊れた PEM を修復する
改行を復元し、BOM と CR を取り除いてください。修復後の BEGIN 行は、ダッシュ 5 個、ラベル、ダッシュ 5 個の並びと正確に一致していなければなりません。
bash printf '%s' "$PEM_VAR" | sed 's/\\n/\n/g' | sed '1s/^\xef\xbb\xbf//' | tr -d '\r' > fixed.pem head -1 fixed.pem # -----BEGIN CERTIFICATE----- - 3.
Node ではパースの前に正規化する
同じエラーは、X509Certificate と tls.createSecureContext() の cert オプションから、ERR_OSSL_PEM_NO_START_LINE というコードで発生します。ほとんどの場合、環境変数の改行を修正すれば解決します。鍵を読み込む関数(createPublicKey、createPrivateKey)は、パースできない入力を代わりに「error:1E08010C:DECODER routines::unsupported」として報告します。
js import { X509Certificate } from "node:crypto"; const cert = new X509Certificate(process.env.CERT_PEM.replace(/\\n/g, "\n"));