{"record":{"id":"bf15b302c491a85a","repo":"denoland/deno","slug":"a-key-and-certificate-are-required-for-deno-liste","errorCode":null,"errorMessage":"A key and certificate are required for `Deno.listenTls`","messagePattern":"A key and certificate are required for `Deno\\.listenTls`","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/net/02_tls.js","lineNumber":179,"sourceCode":"    return op_tls_key_null();\n  }\n}\n\nfunction listenTls({\n  port = 0,\n  hostname = \"0.0.0.0\",\n  transport = \"tcp\",\n  alpnProtocols = undefined,\n  reusePort = false,\n  tcpBacklog = 511,\n}) {\n  if (transport !== \"tcp\") {\n    throw new TypeError(`Unsupported transport: '${transport}'`);\n  }\n  port = validatePort(port, true);\n\n  if (!hasTlsKeyPairOptions(arguments[0])) {\n    throw new TypeError(\n      \"A key and certificate are required for `Deno.listenTls`\",\n    );\n  }\n  const keyPair = loadTlsKeyPair(\"Deno.listenTls\", arguments[0]);\n  const { 0: rid, 1: localAddr } = op_net_listen_tls(\n    { hostname, port },\n    { alpnProtocols, reusePort, tcpBacklog },\n    keyPair,\n  );\n  localAddr.transport = transport;\n  return new TlsListener(rid, localAddr);\n}\n\n// deno-lint-ignore require-await\nasync function startTls(\n  conn,\n  {\n    hostname = \"127.0.0.1\",","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/net/02_tls.js#L161-L197","documentation":"Unlike Deno.connectTls (where cert/key are optional client certificates), a TLS server must present a certificate. listenTls checks hasTlsKeyPairOptions() on the original arguments and throws this TypeError when neither cert nor key is present - a TLS listener cannot start keyless.","triggerScenarios":"Deno.listenTls({ port: 443 }) with no cert/key; passing them under wrong property names; nesting them inside another object so destructuring misses them.","commonSituations":"Local prototypes assuming the runtime auto-generates a self-signed certificate (browsers' dev-cert behavior); migrating from dev servers that auto-provision certs; CI where secret env vars are not yet injected.","solutions":["Generate a self-signed pair for development: openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 365 -subj '/CN=localhost'","Pass both as PEM strings: cert: await Deno.readTextFile('cert.pem'), key: await Deno.readTextFile('key.pem')","In production use real certificates (e.g. Let's Encrypt) injected via secrets/env at startup"],"exampleFix":"// before\nconst listener = Deno.listenTls({ port: 443 }); // TypeError\n\n// after\nconst listener = Deno.listenTls({\n  port: 443,\n  cert: await Deno.readTextFile(\"cert.pem\"),\n  key: await Deno.readTextFile(\"key.pem\"),\n});","handlingStrategy":"validation","validationCode":"async function loadTlsOptions(): Promise<{ cert: string; key: string }> {\n  const certPath = Deno.env.get(\"TLS_CERT_PATH\");\n  const keyPath = Deno.env.get(\"TLS_KEY_PATH\");\n  if (!certPath || !keyPath) {\n    throw new Error(\n      \"listenTls requires a certificate and key - set TLS_CERT_PATH and TLS_KEY_PATH (generate a self-signed pair for dev: openssl req -x509 -newkey rsa:2048 -nodes ...)\",\n    );\n  }\n  return { cert: await Deno.readTextFile(certPath), key: await Deno.readTextFile(keyPath) };\n}","typeGuard":"function hasTlsCertAndKey(o: { cert?: string; key?: string }): o is { cert: string; key: string } {\n  return typeof o.cert === \"string\" && typeof o.key === \"string\" && o.cert !== \"\" && o.key !== \"\";\n}","tryCatchPattern":null,"preventionTips":["Generate a committed-for-dev self-signed pair and document the openssl command","Fail fast at startup when TLS paths are unset instead of calling listenTls","Distinguish server usage (cert/key mandatory) from client usage (optional mTLS) in your config schema"],"tags":["tls","certificates","server","validation","deno"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}