{"record":{"id":"e800aac59f2a83d0","repo":"denoland/deno","slug":"failed-to-get-ecdh-public-key","errorCode":null,"errorMessage":"Failed to get ECDH public key","messagePattern":"Failed to get ECDH public key","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/diffiehellman.ts","lineNumber":1525,"sourceCode":"      pubbuf[0] = compressedBuf[0] + 4;\n    }\n\n    return ecdhEncode(pubbuf, encoding ?? \"buffer\");\n  }\n\n  getPrivateKey(encoding?: any): Buffer | string {\n    if (this.#privbuf === null) {\n      throw new Error(\"Failed to get ECDH private key\");\n    }\n    return ecdhEncode(this.#privbuf, encoding ?? \"buffer\");\n  }\n\n  getPublicKey(\n    encoding?: any,\n    format: any = \"uncompressed\",\n  ): Buffer | string {\n    if (this.#pubbuf === null) {\n      throw new Error(\"Failed to get ECDH public key\");\n    }\n    validateEcdhFormat(format);\n    const pubbuf = Buffer.from(op_node_ecdh_encode_pubkey(\n      this.#curve.name,\n      this.#pubbuf,\n      format === \"compressed\",\n    ));\n    if (format === \"hybrid\") {\n      const compressedBuf = Buffer.from(op_node_ecdh_encode_pubkey(\n        this.#curve.name,\n        this.#pubbuf,\n        true,\n      ));\n      pubbuf[0] = compressedBuf[0] + 4;\n    }\n    return ecdhEncode(pubbuf, encoding ?? \"buffer\");\n  }\n","sourceCodeStart":1507,"sourceCodeEnd":1543,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/diffiehellman.ts#L1507-L1543","documentation":"getPublicKey() throws when the instance's public key buffer (#pubbuf) is null. The public key is populated by generateKeys(), by setPrivateKey() (which derives it), or by the deprecated setPublicKey(); calling getPublicKey() before any of those leaves nothing to return.","triggerScenarios":"createECDH(curve).getPublicKey() before generateKeys(); getPublicKey() after only failed key-import attempts; instances built by constructor injection where the key-setup call was skipped.","commonSituations":"Server boot code that exports its public key for handshake messages before the key pair is generated; unit tests constructing ECDH objects via a factory that forgets generateKeys(); order-of-initialization bugs in DI containers.","solutions":["Call ecdh.generateKeys() immediately after createECDH() and before any getPublicKey()","If importing an existing key, call setPrivateKey(priv) — it computes and stores the public key","Audit factory/builder functions to guarantee a key exists before the object is returned"],"exampleFix":"// before\nconst ecdh = crypto.createECDH('prime256v1');\nsendHello(ecdh.getPublicKey());\n\n// after\nconst ecdh = crypto.createECDH('prime256v1');\necdh.generateKeys();\nsendHello(ecdh.getPublicKey());","handlingStrategy":"validation","validationCode":"function getPub(ecdh: crypto.ECDH): Buffer {\n  try {\n    return ecdh.getPublicKey();\n  } catch {\n    ecdh.generateKeys();\n    return ecdh.getPublicKey();\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate keys before publishing the public key in any hello/handshake message","Build ECDH objects through one factory that ends with generateKeys()","Add an integration test that walks your real init order"],"tags":["crypto","ecdh","key-management","node-compat"],"backgroundTag":"ecdh-missing-public-key","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}