CherryHQ/cherry-studio · error · Error
Invalid PEM format: missing BEGIN/END markers or key content
Error message
Invalid PEM format: missing BEGIN/END markers or key content
What it means
normalizePemFormat runs when the input already contains both BEGIN and END markers. It scans lines between the markers to extract key content; if it never sees a clean BEGIN/END pair or finds no content lines, the PEM is structurally broken and it throws. This catches malformed markers (e.g. extra text, wrong marker name, duplicated headers).
Source
Thrown at packages/aiCore/src/core/providers/core/utils.ts:61
let foundBegin = false
let foundEnd = false
for (const line of lines) {
if (line === '-----BEGIN PRIVATE KEY-----') {
foundBegin = true
continue
}
if (line === '-----END PRIVATE KEY-----') {
foundEnd = true
break
}
if (foundBegin && !foundEnd) {
keyContent += line
}
}
if (!foundBegin || !foundEnd || !keyContent) {
throw new Error('Invalid PEM format: missing BEGIN/END markers or key content')
}
// 重新格式化为 64 字符一行
const formattedContent = keyContent.match(/.{1,64}/g)?.join('\n') || keyContent
return `-----BEGIN PRIVATE KEY-----\n${formattedContent}\n-----END PRIVATE KEY-----`
}
/**
* 重新构建 PEM 私钥
*/
function reconstructPemKey(key: string): string {
// 移除所有空白字符和可能存在的不完整头尾
let cleanKey = key.replace(/\s+/g, '')
cleanKey = cleanKey.replace(/-----BEGIN[^-]*-----/g, '')
cleanKey = cleanKey.replace(/-----END[^-]*-----/g, '')
// 确保私钥内容不为空View on GitHub (pinned to 726446b54c)
Solutions
- Re-export the key in standard PEM format with markers on their own lines.
- Strip surrounding quotes and normalize newlines before calling formatPrivateKey.
- If the key uses a different header (e.g. RSA PRIVATE KEY), convert it to PKCS#8 'PRIVATE KEY' format first.
Example fix
// before — markers glued to content
formatPrivateKey('-----BEGIN PRIVATE KEY-----MIIEvQ...-----END PRIVATE KEY-----')
// after — proper newlines (or let reconstructPemKey rebuild by removing the markers first)
formatPrivateKey('-----BEGIN PRIVATE KEY-----\nMIIEvQ...\n-----END PRIVATE KEY-----') Defensive patterns
Strategy: validation
Validate before calling
function looksLikeValidPem(key: string): boolean {
const lines = key.split('\n').map((l) => l.trim()).filter(Boolean)
return lines[0] === '-----BEGIN PRIVATE KEY-----' && lines[lines.length - 1] === '-----END PRIVATE KEY-----' && lines.length > 2
}
if (!looksLikeValidPem(privateKey)) throw new Error('PEM markers must be on their own lines')
formatPrivateKey(privateKey) Prevention
- Re-export keys in standard PEM with markers on their own lines.
- Normalize newlines and strip quotes before calling formatPrivateKey.
- Convert non-PKCS#8 headers to 'PRIVATE KEY' format first.
When it happens
Trigger: The key string contains '-----BEGIN PRIVATE KEY-----' and '-----END PRIVATE KEY-----' substrings but the line-by-line scan fails: markers glued onto base64 content, wrong marker type, or content only on the same line as the marker.
Common situations: A PEM where BEGIN/END are not on their own lines (minified); markers for a different key type pasted in (e.g. EC PRIVATE KEY with PRIVATE KEY markers expected); copy-paste that merged lines; a key with stray whitespace/quotes breaking exact line equality.
Related errors
- Private key content is empty after cleaning
- Private key contains invalid characters (not valid Base64)
- Private key must be a non-empty string
- Invalid token response from QQ API: ${errorText}
- Rerank response results must reference a valid document inde
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/6ce6e8ecfbab7dab.
Report an issue: GitHub.