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

  1. Re-export the key in standard PEM format with markers on their own lines.
  2. Strip surrounding quotes and normalize newlines before calling formatPrivateKey.
  3. 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

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


AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12). Data as JSON: /api/errors/6ce6e8ecfbab7dab. Report an issue: GitHub.