How to fix Error: Invalid public key format (key parsing failed) in Node.js

Node.jsINTERMEDIATEMEDIUMUpdated Dec 9, 2025ยท 178 views

This error occurs when Node.js crypto module cannot parse a public key because it is in an incorrect format, has encoding issues, or lacks proper structure. The crypto.createPublicKey() function expects keys in specific formats like PEM or DER with correct headers and encoding.

Quick fix

Fixes Error: Invalid public key format (key parsing failed)

// Correct PEM public key format
const validPEM = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----`;

const crypto = require('crypto');
const publicKey = crypto.createPublicKey(validPEM);
  1. Verify PEM format headers and structure
  2. Validate the key using OpenSSL
  3. Specify the correct format explicitly
  4. Handle base64-encoded keys properly
node.js โ€” error
// Correct PEM public key format
const validPEM = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----`;
const crypto = require('crypto');
const publicKey = crypto.createPublicKey(validPEM);
Error: Invalid public key format (key parsing failed)

What this error means

This error is thrown by Node.js's crypto module when attempting to create or use a public key that cannot be successfully parsed. The crypto functions like createPublicKey(), publicEncrypt(), or publicDecrypt() require keys to follow strict formatting standards defined by cryptographic specifications. The most common scenario is when working with PEM-encoded keys that lack proper headers (-----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY-----), have incorrect line breaks, or contain corrupted data. The error can also occur when there's a mismatch between the declared format (PEM, DER, JWK) and the actual key data structure. Node.js uses OpenSSL under the hood for cryptographic operations, and this error typically indicates that the underlying OpenSSL library cannot interpret the key data according to the specified format.

Typical symptoms

  • Error thrown when calling crypto.createPublicKey() with key data
  • publicEncrypt() or publicDecrypt() operations fail with parsing error
  • JWT verification fails with key format errors
  • Key import operations from external sources (files, APIs) fail
  • Error message includes "key parsing failed" or "Invalid public key format"
  • Works with some keys but fails with others from different sources

Common causes

  1. PEM key missing required headers (-----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY-----)
  2. Incorrect line breaks or whitespace in PEM-encoded keys
  3. Attempting to use DER format with X.509 certificates (not supported)
  4. Passing a string when JWK format is specified (JWK requires an object)
  5. Base64-encoded key not properly decoded before use
  6. Key file corrupted or incomplete during transfer
  7. Using wrong key type for the operation (RSA key where EC key expected)
  8. Encoding mismatch between declared format and actual key data
  9. Extra characters or whitespace added when copying keys
  10. Using a private key where a public key is required

How to fix "Error: Invalid public key format (key parsing failed)"

1Verify PEM format headers and structure

If using PEM format, ensure your key has the correct headers and structure:

javascript
// Correct PEM public key format
const validPEM = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----`;

const crypto = require('crypto');
const publicKey = crypto.createPublicKey(validPEM);

Check that:
- Headers are present and exactly match the format above
- There are no extra spaces before or after the headers
- The base64 content is between the headers
- Line breaks are preserved (typically 64 characters per line)

2Validate the key using OpenSSL

Use OpenSSL to verify the key is valid before using it in Node.js:

bash
# Validate and display public key
openssl pkey -in public-key.pem -pubin -text -noout

# Convert DER to PEM if needed
openssl pkey -inform DER -in public-key.der -pubin -outform PEM -out public-key.pem

If OpenSSL reports errors, the key file is corrupted or in an unexpected format.

3Specify the correct format explicitly

When creating a public key, explicitly specify the format to avoid ambiguity:

javascript
const crypto = require('crypto');
const fs = require('fs');

// For PEM format (string)
const pemKey = fs.readFileSync('public-key.pem', 'utf8');
const publicKey = crypto.createPublicKey({
  key: pemKey,
  format: 'pem',
  type: 'spki'  // SubjectPublicKeyInfo
});

// For DER format (buffer)
const derKey = fs.readFileSync('public-key.der');
const publicKey2 = crypto.createPublicKey({
  key: derKey,
  format: 'der',
  type: 'spki'
});

// For JWK format (object, not string)
const jwkKey = {
  kty: 'RSA',
  n: 'base64url_encoded_modulus...',
  e: 'AQAB'
};
const publicKey3 = crypto.createPublicKey({
  key: jwkKey,
  format: 'jwk'
});
4Handle base64-encoded keys properly

If the key is base64-encoded (common when received from APIs), decode it first:

javascript
const crypto = require('crypto');

// Key received as base64 string from API
const base64Key = 'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0...';

// Decode base64 to get actual PEM string
const pemKey = Buffer.from(base64Key, 'base64').toString('utf8');

// Now create the public key
const publicKey = crypto.createPublicKey(pemKey);

Common mistake: Passing the base64 string directly without decoding.

5Remove extra whitespace and normalize line breaks

Clean the key string to remove common formatting issues:

javascript
function normalizeKeyFormat(keyString) {
  // Remove leading/trailing whitespace
  let normalized = keyString.trim();

  // Ensure consistent line breaks (LF instead of CRLF)
  normalized = normalized.replace(/\r\n/g, '\n');

  // Remove any extra spaces within the key
  normalized = normalized.replace(/ +/g, ' ');

  return normalized;
}

const rawKey = `  -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----  `;

const cleanKey = normalizeKeyFormat(rawKey);
const publicKey = crypto.createPublicKey(cleanKey);
6Extract public key from private key if needed

If you only have a private key but need the public key, extract it:

javascript
const crypto = require('crypto');
const fs = require('fs');

// Load private key
const privateKey = crypto.createPrivateKey(
  fs.readFileSync('private-key.pem', 'utf8')
);

// Extract public key from private key
const publicKey = crypto.createPublicKey(privateKey);

// Export in desired format
const publicKeyPEM = publicKey.export({
  type: 'spki',
  format: 'pem'
});

console.log(publicKeyPEM);

Advanced notes

Format Compatibility Matrix:

- PEM + X.509 certificate: Supported for createPublicKey()
- DER + X.509 certificate: NOT supported (use PEM instead)
- JWK format: Key parameter must be a JavaScript object, not a stringified JSON
- PKCS#1 vs SPKI: Use type 'spki' for public keys, 'pkcs1' is for RSA-specific format

JWK Format Gotchas:

When using JWK format with createPublicKey(), there have been documented robustness issues in Node.js versions before v18. If you encounter errors with JWK, consider converting to PEM format as a workaround.

Performance Considerations:

Starting with Node.js v17, there was a documented performance regression in createPublicKey() and createPrivateKey() APIs. If parsing many keys in a loop, consider caching the KeyObject instances rather than recreating them.

Debugging Techniques:

To see exactly what Node.js receives:

javascript
console.log('Key type:', typeof key);
console.log('Key length:', key.length);
console.log('First 50 chars:', key.substring(0, 50));
console.log('Last 50 chars:', key.substring(key.length - 50));

Common Third-Party Integration Issues:

When importing keys from cloud providers (AWS KMS, Azure Key Vault, GCP KMS), the keys are often returned in JWK format or base64-encoded PEM. Always check the provider's documentation for the exact format returned and apply the appropriate decoding/transformation.

Frequently asked questions

What does "Error: Invalid public key format (key parsing failed)" mean?
js's crypto module when attempting to create or use a public key that cannot be successfully parsed. The crypto functions like createPublicKey(), publicEncrypt(), or publicDecrypt() require keys to follow strict formatting standards defined by cryptographic specifications. The most common scenario is when working with PEM-encoded keys that lack proper headers (-----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY-----), have incorrect line breaks, or contain corrupted data.
How do I fix "Error: Invalid public key format (key parsing failed)"?
This error occurs when Node.js crypto module cannot parse a public key because it is in an incorrect format, has encoding issues, or lacks proper structure. The crypto.createPublicKey() function expects keys in specific formats like PEM or DER with correct headers and encoding.
What causes "Error: Invalid public key format (key parsing failed)"?
PEM key missing required headers (-----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY-----) Incorrect line breaks or whitespace in PEM-encoded keys Attempting to use DER format with X.509 certificates (not supported)
Is the "Error: Invalid public key format (key parsing failed)" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading