react/create-react-app · error · Error

The certificate key "${keyFile}" is invalid.\n${err.message}

Error message

The certificate key "${keyFile}" is invalid.\n${err.message}

What it means

After validating the certificate, getHttpsConfig.validateKeyAndCerts attempts to decrypt the test buffer with crypto.privateDecrypt using the supplied key. If that throws, the key is invalid or does not match the certificate, and the error is re-thrown naming keyFile and the underlying message.

Source

Thrown at packages/react-scripts/config/getHttpsConfig.js:34

// Ensure the certificate and key provided are valid and if not
// throw an easy to debug error
function validateKeyAndCerts({ cert, key, keyFile, crtFile }) {
  let encrypted;
  try {
    // publicEncrypt will throw an error with an invalid cert
    encrypted = crypto.publicEncrypt(cert, Buffer.from('test'));
  } catch (err) {
    throw new Error(
      `The certificate "${chalk.yellow(crtFile)}" is invalid.\n${err.message}`
    );
  }

  try {
    // privateDecrypt will throw an error with an invalid key
    crypto.privateDecrypt(key, encrypted);
  } catch (err) {
    throw new Error(
      `The certificate key "${chalk.yellow(keyFile)}" is invalid.\n${
        err.message
      }`
    );
  }
}

// Read file and throw an error if it doesn't exist
function readEnvFile(file, type) {
  if (!fs.existsSync(file)) {
    throw new Error(
      `You specified ${chalk.cyan(
        type
      )} in your env, but the file "${chalk.yellow(file)}" can't be found.`
    );
  }
  return fs.readFileSync(file);
}

View on GitHub (pinned to 6254386531)

Solutions

  1. Ensure SSL_KEY_FILE is the unencrypted PEM private key matching SSL_CRT_FILE (same keypair).
  2. If the key is passphrase-protected, decrypt it: `openssl rsa -in enc.key -out key.pem`, or regenerate without a passphrase.
  3. Verify the PEM key footer/header (`-----BEGIN PRIVATE KEY-----` / `-----END PRIVATE KEY-----`).
  4. Regenerate both cert and key together so they stay a matched pair.

Example fix

# before
SSL_CRT_FILE=./cert.pem
SSL_KEY_FILE=./encrypted.key   # passphrase-protected
# after
SSL_CRT_FILE=./cert.pem
SSL_KEY_FILE=./key.pem         # unencrypted, matching private key
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
const crypto = require('crypto');
function validateKeyFile(certFile, keyFile) {
  const cert = fs.readFileSync(certFile);
  const key = fs.readFileSync(keyFile);
  const enc = crypto.publicEncrypt(cert, Buffer.from('test'));
  try { crypto.privateDecrypt(key, enc); }
  catch (e) { throw new Error(`SSL_KEY_FILE invalid or mismatched: ${e.message}`); }
}
if (process.env.SSL_CRT_FILE && process.env.SSL_KEY_FILE) {
  validateKeyFile(process.env.SSL_CRT_FILE, process.env.SSL_KEY_FILE);
}

Type guard

const looksLikePemKey = (contents) =>
  /-----BEGIN (?:RSA )?PRIVATE KEY-----/.test(contents);

Try / catch

try {
  require('react-scripts/config/getHttpsConfig');
} catch (e) {
  if (/certificate key .* is invalid/i.test(e.message)) {
    console.error('SSL_KEY_FILE invalid or does not match SSL_CRT_FILE.');
    process.exit(1);
  }
  throw e;
}

Prevention

When it happens

Trigger: SSL_KEY_FILE is set to a file that is not a valid private key, or is a valid key that does not correspond to the certificate in SSL_CRT_FILE. crypto.privateDecrypt throws and the catch re-wraps the error.

Common situations: Regenerating the cert but forgetting to regenerate/swap the key. Using an encrypted (passphrase-protected) key that Node cannot read unattended. Key/cert from different pairs. Truncated or mis-formatted PEM key.

Understand the failure class

Related errors


AI-assisted analysis of react/create-react-app@6254386531 (2026-08-12). Data as JSON: /api/errors/0cc3c074dfdcc66a. Report an issue: GitHub.