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

  1. 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.
  2. 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`.
  3. 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.
  4. 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

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

Related errors


AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12). Data as JSON: /api/errors/3c1a0015ac016a70. Report an issue: GitHub.