{"record":{"id":"476df96f9ba72659","repo":"denoland/deno","slug":"if-keyformat-is-specified-it-must-be-pem-rec","errorCode":null,"errorMessage":"If \"keyFormat\" is specified, it must be \"pem\": received \"${keyFormat}\"","messagePattern":"If \"keyFormat\" is specified, it must be \"pem\": received \"(.+?)\"","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/net/02_tls.js","lineNumber":142,"sourceCode":"}\n\n/**\n * Loads a TLS keypair from one of the various options. If no key material is provided,\n * returns a special Null keypair.\n */\nfunction 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 {","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/net/02_tls.js#L124-L160","documentation":"connectTls/listenTls accept an optional keyFormat option, but loadTlsKeyPair() implements only 'pem': any defined value other than 'pem' throws this TypeError. Leaving keyFormat undefined is fine and implies PEM.","triggerScenarios":"Deno.connectTls({ ..., cert, key, keyFormat: 'der' }); listenTls with keyFormat: 'pkcs8'; any non-'pem' string.","commonSituations":"Porting code from libraries whose key APIs accept multiple encodings (Node's DER/PEM distinctions, JWT libraries); hand-rolling cert option objects from examples that include keyFormat.","solutions":["Drop the keyFormat option - PEM is the default and only supported format","If your keys are DER, convert them first: openssl pkey -inform DER -outform PEM -in key.der -out key.pem","Pass the PEM file contents as strings for cert and key"],"exampleFix":"// before\nawait Deno.connectTls({ hostname, port, cert: derCert, key: derKey, keyFormat: \"der\" });\n\n// after\nawait Deno.connectTls({ hostname, port, cert: pemCert, key: pemKey });","handlingStrategy":"validation","validationCode":"function normalizeKeyFormat(fmt: string | undefined): \"pem\" | undefined {\n  if (fmt !== undefined && fmt !== \"pem\") {\n    throw new Error(`Only PEM keys are supported; convert DER first (openssl pkey -inform DER -outform PEM)`);\n  }\n  return fmt;\n}","typeGuard":"function isPemKeyFormat(f: unknown): boolean {\n  return f === undefined || f === \"pem\";\n}","tryCatchPattern":null,"preventionTips":["Standardize on PEM files for all certs/keys in the project","Do not copy keyFormat examples from other runtimes' APIs","Store the conversion command (openssl pkey) next to your key tooling for DER artifacts"],"tags":["tls","crypto","keys","pem","validation","deno"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}