错误信息
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”。与之相关的另一个错误是“error:04800066:PEM routines::bad end line”,出现在 END 标记损坏时。
OpenSSL 3.x — also surfaces in Node as ERR_OSSL_PEM_NO_START_LINE
含义
PEM 解析器在输入中查找与它所需对象相匹配的“-----BEGIN ...-----”行,但一行也没有找到。原因要么是文件根本不是 PEM(而是二进制 DER、JSON 或空文件),要么是 BEGIN 标签指明的对象与解析器需要的不同,要么是封装结构在传递过程中被破坏了。
原因
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 输出就能区分 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 行必须恰好由五个短横线、标签和五个短横线组成。
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"));