facebook/docusaurus · error · Error
HTTPS support require proving a certificate and key at the s
Error message
HTTPS support require proving a certificate and key at the same time.\nYou only provided a ${cert ? 'certificate' : 'key'} (with ${fileProvided.source}) at path path=${fileProvided.path}. What it means
Thrown by ensureCertKeyBothProvided() when exactly one of {cert, key} is resolved (an XOR: `(cert || key) && !(cert && key)`). Docusaurus requires both a certificate and a private key together for HTTPS. The message reports which one you supplied and through which {source} (CLI arg or env var) and at which path, so you can supply the missing counterpart. Cert/key are resolved independently from options.sslCert / DOCUSAURUS_SSL_CRT_FILE / SSL_CRT_FILE and options.sslKey / DOCUSAURUS_SSL_KEY_FILE / SSL_KEY_FILE respectively.
Source
Thrown at packages/docusaurus/src/webpack/utils/getHttpsConfig.ts:152
'env DOCUSAURUS_SSL_KEY_FILE',
);
}
if (process.env.SSL_KEY_FILE) {
return readCryptoFile(
path.resolve(cwd, process.env.SSL_KEY_FILE),
'env SSL_KEY_FILE',
);
}
return null;
}
function ensureCertKeyBothProvided(
cert: CryptoFile | null,
key: CryptoFile | null,
) {
if ((cert || key) && !(cert && key)) {
const fileProvided = (cert ?? key)!;
throw new Error(
logger.interpolate`HTTPS support require proving a certificate and key at the same time.
You only provided a ${cert ? 'certificate' : 'key'} (with ${fileProvided.source}) at path path=${fileProvided.path}.`,
);
}
}
// Get the https config
// Return cert files if provided via CLI or env, otherwise just true or false.
// CLI options take precedence over env vars.
export default async function getHttpsConfig(
options: Partial<HttpsConfigOptions> = {},
): Promise<boolean | {cert: Buffer; key: Buffer}> {
const cwd = await fs.realpath(process.cwd());
const [cert, key] = await Promise.all([
getCert(options, cwd),
getKeyFile(options, cwd),
]);View on GitHub (pinned to 3f483e80e3)
Solutions
- Read the {source}/{path} in the message: it tells you whether you provided a cert or a key, and via CLI arg or env var.
- Supply the missing counterpart through the same channel (both via CLI flags, or both via env vars) — e.g. add `--ssl-key ./key.pem` alongside `--ssl-cert ./cert.pem`.
- Unset stale env vars from the other half so only an explicit, intentional pair remains: `unset SSL_CRT_FILE` if you now pass certs on the CLI.
- Confirm both files exist and are readable (or you will then hit error 160/161).
Example fix
// before DOCUSAURUS_SSL_CRT_FILE=./cert.pem docusaurus start --https // after DOCUSAURUS_SSL_CRT_FILE=./cert.pem DOCUSAURUS_SSL_KEY_FILE=./key.pem docusaurus start --https
Defensive patterns
Strategy: validation
Validate before calling
function validateHttpsCertKeyPair(opts: {
sslCert?: string; sslKey?: string;
env = process.env;
}) {
const certSrc = opts.sslCert ?? opts.env.DOCUSAURUS_SSL_CRT_FILE ?? opts.env.SSL_CRT_FILE;
const keySrc = opts.sslKey ?? opts.env.DOCUSAURUS_SSL_KEY_FILE ?? opts.env.SSL_KEY_FILE;
if ((certSrc || keySrc) && !(certSrc && keySrc)) {
throw new Error(
`HTTPS needs BOTH cert and key. Got cert=${certSrc ?? '(none)'}, key=${keySrc ?? '(none)'}.`,
);
}
}
// call before getHttpsConfig(): validateHttpsCertKeyPair({ sslCert, sslKey }); Type guard
const hasBothCertAndKey = (o: {sslCert?: string; sslKey?: string}, env = process.env) =>
Boolean((o.sslCert ?? env.DOCUSAURUS_SSL_CRT_FILE ?? env.SSL_CRT_FILE) &&
(o.sslKey ?? env.DOCUSAURUS_SSL_KEY_FILE ?? env.SSL_KEY_FILE)); Prevention
- Always set cert and key through the same channel (both CLI flags or both env vars).
- Run `env | grep -i ssl` to spot stale env vars leaking from shell profiles.
- Keep a single npm script that passes both flags together, so contributors never set just one.
When it happens
Trigger: Setting only DOCUSAURUS_SSL_CRT_FILE without a matching DOCUSAURUS_SSL_KEY_FILE (or vice versa); passing --ssl-cert but forgetting --ssl-key; having a stale SSL_CRT_FILE env var from another project while only providing the key explicitly now.
Common situations: Copy-pasting half of an HTTPS setup from docs; env vars leaking from a shell profile (export SSL_CRT_FILE=...) so the cert is silently picked up even though you only intended to set the key; switching from one machine to another where only one of the two env vars is exported.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- The certificate path=${cert.path} is invalid.
- The certificate key path=${key.path} is invalid.
- The certificate path=${cert.path} and key path=${key.path} d
- You specified ${source}, but file at path path=${filepath} c
- You specified ${source}, but file at path path=${filepath} c
AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12).
Data as JSON: /api/errors/3c1a0015ac016a70.
Report an issue: GitHub.