Message d’erreur
Unable to load PEM file. See https://cryptography.io/en/latest/faq/#why-can-t-i-import-my-pem-file for more details. MalformedFraming
La phrase qui précède le jeton est fixe ; le jeton indique ce qui s’est mal passé. MalformedFraming signifie que les lignes BEGIN/END sont introuvables ; MismatchedTags("PRIVATE KEY", "PUBLIC KEY") signifie qu’elles ne concordent pas ; InvalidData(Invalid symbol 92, offset 0.) signifie que le corps n’est pas du base64 : 92 est une barre oblique inverse, signe de séquences \n littérales.
Python cryptography — ValueError from load_pem_* functions
Ce que cela signifie
load_pem_private_key / load_pem_public_key / load_pem_x509_certificate n’a pas trouvé d’encadrement PEM intact, c’est-à-dire des lignes BEGIN et END concordantes entourant un corps base64. Le jeton final (ici MalformedFraming) est le diagnostic de l’analyseur ; le lien vers la FAQ fait partie du texte même de l’erreur.
Pourquoi cela se produit
PEM tronqué ou partiellement copié
fréquenteUne ligne END manquante (presse-papiers tronqué, scalaire de bloc YAML qui avale la dernière ligne) casse l’encadrement. Chaque PEM doit se terminer par la ligne -----END ...----- correspondante. Une valeur vide (un secret non défini) produit le même MalformedFraming.
Sauts de ligne échappés dans l’environnement ou la configuration
fréquenteLes PEM transmis par des fichiers .env, docker-compose, des manifestes Kubernetes ou du JSON arrivent souvent sur une seule ligne avec des séquences \n littérales. Le chargeur signale la même phrase avec InvalidData(Invalid symbol 92, offset 0.) à la fin.
Marqueurs BEGIN ou END endommagés
occasionnelleUn marqueur qui a perdu un tiret, ou des caractères ressemblant à des tirets collés depuis un éditeur de documents, n’encadrent plus le bloc ; un libellé END différent du libellé BEGIN est signalé comme MismatchedTags. Ce que cryptography 50 tolère : des guillemets autour du bloc, l’indentation YAML, un BOM UTF-8 et les fins de ligne CRLF.
Bundle concaténé avec un séparateur endommagé
rareLes fichiers de chaîne contenant plusieurs blocs PEM échouent dans leur ensemble lorsqu’un des blocs a perdu sa ligne END : le chargeur signale alors InvalidData(Invalid symbol 45, …), 45 étant le premier tiret de la ligne BEGIN suivante. Le chargeur signale le fichier, pas le bloc ; procédez donc par dichotomie : découpez le bundle et chargez chaque objet séparément pour trouver celui qui est endommagé.
Comment corriger l’erreur
- 1.
Normaliser avant le chargement
Rétablissez les sauts de ligne, supprimez les espaces et les guillemets superflus, et vérifiez la première ligne avant de transmettre les octets au chargeur.
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.
Privilégier les fichiers ou les secrets multilignes natifs
Les fichiers de secrets montés évitent entièrement le problème d’échappement ; les Secrets Kubernetes et la plupart des coffres-forts de secrets peuvent fournir le PEM à l’octet près.
python with open("/run/secrets/signing_key.pem", "rb") as f: key = load_pem_private_key(f.read(), password=None) - 3.
Valider mécaniquement l’encadrement
Une vérification rapide de la présence et de la concordance des lignes BEGIN/END permet de déterminer si le défaut vient du contenu ou du transport.
python lines = pem.decode().splitlines() print(lines[0]) # -----BEGIN PRIVATE KEY----- print(lines[-1]) # -----END PRIVATE KEY-----