{"record":{"id":"7c0bdf2360b383c4","repo":"denoland/deno","slug":"if-cert-is-specified-key-must-be-specified-as","errorCode":null,"errorMessage":"If `cert` is specified, `key` must be specified as well for `${api}`","messagePattern":"If `cert` is specified, `key` must be specified as well for `(.+?)`","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/net/02_tls.js","lineNumber":148,"sourceCode":"function loadTlsKeyPair(api, {\n  keyFormat,\n  cert,\n  key,\n}) {\n  // TODO(mmastrac): remove this temporary symbol when the API lands\n  if (arguments[1][resolverSymbol] !== undefined) {\n    return createTlsKeyResolver(arguments[1][resolverSymbol]);\n  }\n\n  // Check for \"pem\" format\n  if (keyFormat !== undefined && keyFormat !== \"pem\") {\n    throw new TypeError(\n      `If \"keyFormat\" is specified, it must be \"pem\": received \"${keyFormat}\"`,\n    );\n  }\n\n  if (cert !== undefined && key === undefined) {\n    throw new TypeError(\n      `If \\`cert\\` is specified, \\`key\\` must be specified as well for \\`${api}\\``,\n    );\n  }\n  if (cert === undefined && key !== undefined) {\n    throw new TypeError(\n      `If \\`key\\` is specified, \\`cert\\` must be specified as well for \\`${api}\\``,\n    );\n  }\n\n  if (cert !== undefined) {\n    return op_tls_key_static(cert, key);\n  } else {\n    return op_tls_key_null();\n  }\n}\n\nfunction listenTls({\n  port = 0,","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/net/02_tls.js#L130-L166","documentation":"loadTlsKeyPair requires cert and key to be passed together; specifying cert without key throws this TypeError, with the message naming the offending API (Deno.connectTls or Deno.listenTls). A TLS identity is inherently a pair - a certificate alone cannot be used, so the check runs before any socket or TLS context is created.","triggerScenarios":"Deno.listenTls({ port: 443, cert: pem }) with no key; Deno.connectTls({ cert }) attempting mutual TLS with a missing client key; destructuring a config object where the key field was dropped (typo, undefined).","commonSituations":"Secrets split across files where only cert.pem got deployed; config objects assembled conditionally so key ends up undefined; examples copied from docs that omitted the key line.","solutions":["Pass both strings: Deno.listenTls({ port, cert: await Deno.readTextFile('cert.pem'), key: await Deno.readTextFile('key.pem') })","Verify both files/env vars exist before building the options object","If you do not need a client certificate, omit cert as well - server-only verification needs neither"],"exampleFix":"// before\nDeno.listenTls({ port: 443, cert }); // key missing\n\n// after\nconst [cert, key] = await Promise.all([\n  Deno.readTextFile('cert.pem'),\n  Deno.readTextFile('key.pem'),\n]);\nDeno.listenTls({ port: 443, cert, key });","handlingStrategy":"validation","validationCode":"function requireKeyPair(opts: { cert?: string; key?: string }): { cert: string; key: string } {\n  if (opts.cert === undefined || opts.key === undefined) {\n    throw new Error('TLS identity requires both cert and key');\n  }\n  return { cert: opts.cert, key: opts.key };\n}","typeGuard":"function hasCompleteKeyPair(o: { cert?: string; key?: string }): o is { cert: string; key: string } {\n  return typeof o.cert === 'string' && typeof o.key === 'string' &&\n    o.cert.length > 0 && o.key.length > 0;\n}","tryCatchPattern":"try {\n  Deno.listenTls(opts);\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('`key` must be specified')) {\n    throw new Error(`missing TLS key file (cert was loaded from ${certPath})`);\n  }\n  throw e;\n}","preventionTips":["Load cert and key in one Promise.all so one missing file fails loudly and early","Validate that both PEM strings are non-empty and contain BEGIN/END markers","For client connections without client certificates, pass neither cert nor key"],"tags":["deno","tls","certificate","private-key","typeerror"],"backgroundTag":"tls-certificate-configuration","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}