denoland/deno · error · TypeError
Unsupported 'certFile' / 'keyFile' options provided: use 'ce
Error message
Unsupported 'certFile' / 'keyFile' options provided: use 'cert' / 'key' instead.
What it means
Early Deno 1.x versions configured HTTPS with file-path options certFile/keyFile. Modern Deno.serve reads certificate and key material directly via the cert and key options (PEM string or Uint8Array), so the old path-shaped keys were removed; passing them now throws this TypeError at startup to force the migration instead of silently ignoring TLS.
Source
Thrown at ext/http/00_serve.ts:1369
formatHostName(listener.addr.hostname)
}${additional}`,
);
}
},
automaticCompression,
);
}
const listenOpts = {
hostname: options.hostname ?? "0.0.0.0",
port: options.port ?? 8000,
reusePort: options.reusePort ?? false,
loadBalanced: options[kLoadBalanced] ?? false,
tcpBacklog: options.tcpBacklog,
};
if (options.certFile || options.keyFile) {
throw new TypeError(
"Unsupported 'certFile' / 'keyFile' options provided: use 'cert' / 'key' instead.",
);
}
if (options.alpnProtocols) {
throw new TypeError(
"Unsupported 'alpnProtocols' option provided. 'h2' and 'http/1.1' are automatically supported.",
);
}
let listener;
if (wantsHttps) {
if (!options.cert || !options.key) {
throw new TypeError(
"Both 'cert' and 'key' must be provided to enable HTTPS",
);
}
listenOpts.cert = options.cert;
listenOpts.key = options.key;View on GitHub (pinned to 89f33cbef2)
Solutions
- Replace certFile/keyFile with cert/key containing the PEM contents: cert: Deno.readTextFileSync('./cert.pem')
- Load keys once at startup and pass the strings/Uint8Arrays to serve
- Keep permissions in mind: reading the files requires --allow-read
Example fix
// before
Deno.serve({
port: 443,
certFile: "./cert.pem",
keyFile: "./key.pem",
handler,
});
// after
Deno.serve({
port: 443,
cert: Deno.readTextFileSync("./cert.pem"),
key: Deno.readTextFileSync("./key.pem"),
handler,
}); Defensive patterns
Strategy: validation
Validate before calling
// Migrate legacy options before calling serve
const { certFile, keyFile, ...rest } = options;
if (certFile || keyFile) {
rest.cert ??= Deno.readTextFileSync(certFile);
rest.key ??= Deno.readTextFileSync(keyFile);
}
Deno.serve({ ...rest, handler }); Type guard
function hasLegacyTlsOptions(o) {
return "certFile" in o || "keyFile" in o;
} Prevention
- Grep codebases for certFile/keyFile before Deno upgrades
- Store PEM contents (or Uint8Arrays) in the cert/key options, never paths
- Run the server with --allow-read only if keys are read at runtime
When it happens
Trigger: Passing certFile: './cert.pem' and/or keyFile: './key.pem' in the serve options object when enabling HTTPS.
Common situations: Upgrading old scripts or deploying tutorials written for early Deno 1.x; copy-pasting TLS config from Node's https.createServer examples adapted to Deno.
Related errors
- Unsupported 'alpnProtocols' option provided. 'h2' and 'http/
- Already upgraded
- Already closed
- Request closed
- Invalid response
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/b149d07a213433f1.
Report an issue: GitHub.