Error message
error:1E08010C:DECODER routines::unsupported
Reproduced on Node 26 / OpenSSL 3.x. The OpenSSL CLI prints the long form: "error:1E08010C:DECODER routines:OSSL_DECODER_from_bio:unsupported". On Node ≤16 (OpenSSL 1.1.1) the same mistakes produced different messages.
Node.js crypto (OpenSSL 3) — code ERR_OSSL_UNSUPPORTED
What it means
OpenSSL 3's decoder could not parse the key material you handed to createPrivateKey(), createPublicKey(), sign() or verify(). Despite the word "unsupported", this is almost never about a missing algorithm — it means the bytes are not a readable key in any format the decoder tried.
Why it happens
PEM from an env var with literal \n
commonSecrets managers and .env files often deliver "-----BEGIN PRIVATE KEY-----\nMIG..." with backslash-n as two characters. OpenSSL sees a one-line file with no valid PEM framing and gives up.
Empty string or non-key content
commonThe variable holds "", a file path (instead of file contents), a JSON blob, or a certificate when a raw key was expected. Anything that is not PEM/DER key material lands on this exact error.
Wrong key class for the API
commonPassing a public key PEM to createPrivateKey() (or a private key where only SPKI is acceptable) fails with this message — the decoder is looking for a private-key structure and finds none.
DER bytes without format metadata
occasionalRaw DER passed as a bare Buffer defaults to PEM parsing. Without { format: "der", type: "pkcs8" | "spki" | "sec1" } the decoder cannot know what structure to expect.
How to fix it
- 1.
Normalize env-provided PEMs and check the label
Restore newlines and print the first line. If the label says PUBLIC KEY where you call createPrivateKey, the variable is wired to the wrong key.
js const pem = process.env.SIGNING_KEY.replace(/\\n/g, "\n"); console.log(pem.split("\n")[0]); // -----BEGIN PRIVATE KEY----- → createPrivateKey(pem) // -----BEGIN PUBLIC KEY----- → createPublicKey(pem) // -----BEGIN EC PRIVATE KEY----- → createPrivateKey(pem) (SEC1, also fine) - 2.
Be explicit about DER
When the key is binary DER (from a database blob, a JWKS conversion, or protobuf), state the format and type; the decoder will not guess.
js import { createPrivateKey } from "node:crypto"; const key = createPrivateKey({ key: derBuffer, format: "der", type: "pkcs8", // or "sec1" for BEGIN EC PRIVATE KEY material }); - 3.
Verify the material outside Node
Let OpenSSL tell you what the bytes actually are. If this also fails, the data itself is damaged — fix the source, not the Node call.
bash openssl pkey -in key.pem -noout -text | head # for DER: openssl pkey -in key.der -inform der -noout -text | head