{"record":{"id":"807bbbe2a9a46735","repo":"facebook/docusaurus","slug":"the-certificate-key-path-key-path-is-invalid","errorCode":null,"errorMessage":"The certificate key path=${key.path} is invalid.","messagePattern":"The certificate key path=(.+?) is invalid\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/docusaurus/src/webpack/utils/getHttpsConfig.ts","lineNumber":34,"sourceCode":"// Works for any key type (RSA, ECDSA, EdDSA, ...) — parses both PEMs and\n// checks that the public key embedded in the cert matches the public key\n// derived from the private key.\nfunction validateKeyAndCerts({cert, key}: {cert: CryptoFile; key: CryptoFile}) {\n  let certPublicKey: crypto.KeyObject;\n  try {\n    certPublicKey = new crypto.X509Certificate(cert.content).publicKey;\n  } catch (error) {\n    throw new Error(\n      logger.interpolate`The certificate path=${cert.path} is invalid.`,\n      {cause: error},\n    );\n  }\n\n  let keyPublicKey: crypto.KeyObject;\n  try {\n    keyPublicKey = crypto.createPublicKey(crypto.createPrivateKey(key.content));\n  } catch (error) {\n    throw new Error(\n      logger.interpolate`The certificate key path=${key.path} is invalid.`,\n      {cause: error},\n    );\n  }\n\n  if (!certPublicKey.equals(keyPublicKey)) {\n    throw new Error(\n      logger.interpolate`The certificate path=${cert.path} and key path=${key.path} do not match.`,\n    );\n  }\n}\n\ntype HttpsConfigOptions = {\n  https: boolean;\n  sslCert: string;\n  sslKey: string;\n};\n","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/facebook/docusaurus/blob/3f483e80e326cc646b54b83d564b3f0c4881b9a6/packages/docusaurus/src/webpack/utils/getHttpsConfig.ts#L16-L52","documentation":"Thrown by `validateKeyAndCerts` when `crypto.createPrivateKey(key.content)` (or the subsequent `createPublicKey`) fails — i.e. the supplied private key is unreadable or in an unsupported format. The original error is attached as `cause`.","triggerScenarios":"Passing `--ssl-key` pointing to a file that is not a valid PEM private key (RSA/ECDSA/EdDSA). The try/catch at getHttpsConfig.ts:31-38 wraps the key-parse failure.","commonSituations":"Key file is encrypted with a passphrase Docusaurus doesn't unlock; wrong format (PKCS#8 vs PKCS#1 vs SEC1); key file is actually the certificate; corruption from copy-paste.","solutions":["Verify the key parses: `openssl pkey -in key.pem -noout`.","If encrypted, decrypt first: `openssl rsa -in encrypted.pem -out plain.pem`.","Use a supported PEM private key format; regenerate via `mkcert` if unsure.","Ensure you are not pointing `sslKey` at the certificate file."],"exampleFix":"# before (encrypted key, no passphrase support)\ndocusaurus start --https --ssl-key ./encrypted.key\n# after (decrypted PEM key)\ndocusaurus start --https --ssl-key ./plain.key","handlingStrategy":"validation","validationCode":"const crypto = require('crypto');\nconst fs = require('fs');\nfunction isValidKey(path: string) {\n  try { crypto.createPrivateKey(fs.readFileSync(path)); return true; } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  validateKeyAndCerts({cert, key});\n} catch (e) {\n  if (/certificate key path=.* is invalid/.test(e.message)) {\n    console.error('SSL key unreadable — use a valid unencrypted PEM key');\n  }\n  throw e;\n}","preventionTips":["Use an unencrypted PEM private key (RSA/ECDSA/EdDSA).","Verify with `openssl pkey -in key.pem -noout` before configuring.","Do not pass the certificate file as the key."],"tags":["https","ssl","dev-server","config"],"backgroundTag":null,"analyzedSha":"3f483e80e326cc646b54b83d564b3f0c4881b9a6","analyzedAt":"2026-08-12T13:25:04.382Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}