{"record":{"id":"b149d07a213433f1","repo":"denoland/deno","slug":"unsupported-certfile-keyfile-options-provide","errorCode":null,"errorMessage":"Unsupported 'certFile' / 'keyFile' options provided: use 'cert' / 'key' instead.","messagePattern":"Unsupported 'certFile' / 'keyFile' options provided: use 'cert' / 'key' instead\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/http/00_serve.ts","lineNumber":1369,"sourceCode":"              formatHostName(listener.addr.hostname)\n            }${additional}`,\n          );\n        }\n      },\n      automaticCompression,\n    );\n  }\n\n  const listenOpts = {\n    hostname: options.hostname ?? \"0.0.0.0\",\n    port: options.port ?? 8000,\n    reusePort: options.reusePort ?? false,\n    loadBalanced: options[kLoadBalanced] ?? false,\n    tcpBacklog: options.tcpBacklog,\n  };\n\n  if (options.certFile || options.keyFile) {\n    throw new TypeError(\n      \"Unsupported 'certFile' / 'keyFile' options provided: use 'cert' / 'key' instead.\",\n    );\n  }\n  if (options.alpnProtocols) {\n    throw new TypeError(\n      \"Unsupported 'alpnProtocols' option provided. 'h2' and 'http/1.1' are automatically supported.\",\n    );\n  }\n\n  let listener;\n  if (wantsHttps) {\n    if (!options.cert || !options.key) {\n      throw new TypeError(\n        \"Both 'cert' and 'key' must be provided to enable HTTPS\",\n      );\n    }\n    listenOpts.cert = options.cert;\n    listenOpts.key = options.key;","sourceCodeStart":1351,"sourceCodeEnd":1387,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/http/00_serve.ts#L1351-L1387","documentation":"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.","triggerScenarios":"Passing certFile: './cert.pem' and/or keyFile: './key.pem' in the serve options object when enabling HTTPS.","commonSituations":"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.","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"],"exampleFix":"// before\nDeno.serve({\n  port: 443,\n  certFile: \"./cert.pem\",\n  keyFile: \"./key.pem\",\n  handler,\n});\n\n// after\nDeno.serve({\n  port: 443,\n  cert: Deno.readTextFileSync(\"./cert.pem\"),\n  key: Deno.readTextFileSync(\"./key.pem\"),\n  handler,\n});","handlingStrategy":"validation","validationCode":"// Migrate legacy options before calling serve\nconst { certFile, keyFile, ...rest } = options;\nif (certFile || keyFile) {\n  rest.cert ??= Deno.readTextFileSync(certFile);\n  rest.key ??= Deno.readTextFileSync(keyFile);\n}\nDeno.serve({ ...rest, handler });","typeGuard":"function hasLegacyTlsOptions(o) {\n  return \"certFile\" in o || \"keyFile\" in o;\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["http","serve","tls","https","migration"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}