Error message
Valid PEM but no BEGIN PUBLIC KEY/END PUBLIC KEY delimiters. Are you sure this is a public key?
Python cryptography — ValueError from load_pem_public_key
What it means
The file is well-formed PEM — the framing parses — but its label is not PUBLIC KEY. You handed load_pem_public_key a private key, a certificate, or a CSR. The library is asking, literally, whether you picked the right loader for this object.
Why it happens
Private key passed to the public-key loader
commonBEGIN PRIVATE KEY / BEGIN EC PRIVATE KEY blocks need load_pem_private_key. This often happens when one config slot ("the key") serves code paths that actually need different halves of the pair.
Certificate where the bare key is expected
commonBEGIN CERTIFICATE contains a public key inside an X.509 structure. It must be loaded as a certificate first, then the key extracted — the PEM label tells you which parser owns the object.
Exotic but valid labels
rareObjects like BEGIN CERTIFICATE REQUEST (CSR) or an OpenSSH-format key pasted into a .pem file also fail this check — each has its own loader or needs conversion.
How to fix it
- 1.
Derive the public key from what you actually have
Every container that holds key material can yield the public key with one extra call.
python from cryptography.hazmat.primitives.serialization import ( load_pem_private_key, load_pem_public_key) from cryptography.x509 import load_pem_x509_certificate first = pem.splitlines()[0] if b"PRIVATE KEY" in first: public_key = load_pem_private_key(pem, password=None).public_key() elif b"CERTIFICATE" in first: public_key = load_pem_x509_certificate(pem).public_key() else: public_key = load_pem_public_key(pem) - 2.
Export a proper SPKI once
If a system needs the bare public key repeatedly, generate the canonical BEGIN PUBLIC KEY file and store that.
bash openssl pkey -in private.pem -pubout -out public.pem # from a private key openssl x509 -in cert.pem -pubkey -noout > public.pem # from a certificate - 3.
Name files by what they contain
Half of these failures are filing errors rather than code errors: a server.pem holding key, certificate and chain concatenated, or a public.pem produced by copying the wrong command's output. Store one object per file with the object type in the name (orders-es256-public.pem) and this whole loader-mismatch class disappears from the codebase.