Mensagem de erro
Unable to load PEM file. See https://cryptography.io/en/latest/faq/#why-can-t-i-import-my-pem-file for more details. MalformedFraming
A frase antes do token é fixa; o token indica o que deu errado. MalformedFraming significa que as linhas BEGIN/END não foram encontradas; MismatchedTags("PRIVATE KEY", "PUBLIC KEY"), que elas não correspondem entre si; InvalidData(Invalid symbol 92, offset 0.), que o corpo não é base64 — 92 é uma barra invertida, sinal de sequências \n literais.
Python cryptography — ValueError from load_pem_* functions
O que significa
As funções load_pem_private_key / load_pem_public_key / load_pem_x509_certificate não encontraram uma delimitação PEM intacta — linhas BEGIN e END correspondentes, com um corpo em base64 entre elas. O token final (aqui, MalformedFraming) é o diagnóstico do parser; o link do FAQ vem dentro do próprio texto do erro.
Por que acontece
PEM truncado ou copiado parcialmente
comumA falta da linha END (área de transferência cortada, um escalar de bloco do YAML que engoliu a última linha) quebra a delimitação. Todo PEM precisa terminar com a linha -----END ...----- correspondente. Um valor vazio — um segredo não definido — produz o mesmo MalformedFraming.
Quebras de linha escapadas vindas do ambiente ou da configuração
comumPEMs entregues por arquivos .env, docker-compose, manifestos do Kubernetes ou JSON muitas vezes chegam como uma única linha com sequências \n literais. O carregador informa a mesma frase com InvalidData(Invalid symbol 92, offset 0.) no final.
Marcadores BEGIN ou END danificados
ocasionalUm marcador que perdeu um traço, ou traços parecidos colados de um editor de documentos, deixam de delimitar o bloco; um rótulo END diferente do rótulo BEGIN é informado como MismatchedTags. O que a biblioteca cryptography 50 tolera: aspas em volta do bloco, indentação YAML, um BOM UTF-8 e finais de linha CRLF.
Pacote concatenado com um separador danificado
raraArquivos de cadeia com vários blocos PEM falham por inteiro quando um bloco perdeu a linha END — o carregador então informa InvalidData(Invalid symbol 45, …), sendo 45 o primeiro traço da linha BEGIN seguinte. O carregador aponta o arquivo, não o bloco — então faça uma bisseção: divida o pacote e carregue cada objeto separadamente para achar o danificado.
Como corrigir
- 1.
Normalizar antes de carregar
Restaure as quebras de linha, remova espaços em branco e aspas e confira a primeira linha antes de passar os bytes ao carregador.
python import os pem = os.environ["PRIVATE_KEY"].replace("\\n", "\n").strip().strip('"').encode() assert pem.startswith(b"-----BEGIN"), pem[:30] from cryptography.hazmat.primitives.serialization import load_pem_private_key key = load_pem_private_key(pem, password=None) - 2.
Preferir arquivos ou segredos multilinha nativos
Arquivos de segredo montados evitam por completo o problema do escape; os Secrets do Kubernetes e a maioria dos cofres de segredos conseguem entregar o PEM idêntico byte a byte.
python with open("/run/secrets/signing_key.pem", "rb") as f: key = load_pem_private_key(f.read(), password=None) - 3.
Validar a delimitação mecanicamente
Uma verificação rápida de que as linhas BEGIN/END existem e correspondem entre si restringe a falha ao conteúdo ou ao transporte.
python lines = pem.decode().splitlines() print(lines[0]) # -----BEGIN PRIVATE KEY----- print(lines[-1]) # -----END PRIVATE KEY-----