{"record":{"id":"91a815ec3c9b979d","repo":"denoland/deno","slug":"failed-to-convert-buffer-to-ec-point","errorCode":null,"errorMessage":"Failed to convert Buffer to EC_POINT","messagePattern":"Failed to convert Buffer to EC_POINT","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/diffiehellman.ts","lineNumber":1422,"sourceCode":"        throw new ERR_CRYPTO_ECDH_INVALID_FORMAT(format);\n      }\n    } else {\n      compress = false;\n    }\n\n    let result;\n    try {\n      result = Buffer.from(\n        op_node_ecdh_encode_pubkey(curve, buf, compress),\n      );\n    } catch (e) {\n      if (\n        ObjectPrototypeIsPrototypeOf(TypeErrorPrototype, e) &&\n        (e as Error).message === \"Unsupported curve\"\n      ) {\n        throw new TypeError(\"Invalid EC curve name\");\n      }\n      throw new Error(\"Failed to convert Buffer to EC_POINT\");\n    }\n\n    if (format === \"hybrid\") {\n      // Hybrid format: same as uncompressed but first byte is 06 or 07\n      // Get compressed form to determine parity\n      const compressedBuf = Buffer.from(\n        op_node_ecdh_encode_pubkey(curve, buf, true),\n      );\n      // compressed first byte is 02 (even) or 03 (odd)\n      // hybrid first byte is 06 (even) or 07 (odd)\n      result[0] = compressedBuf[0] + 4;\n    }\n\n    if (outputEncoding && outputEncoding !== \"buffer\") {\n      // deno-lint-ignore deno-internal/prefer-primordials -- Buffer.prototype.toString(encoding) has no primordial\n      return result.toString(outputEncoding);\n    }\n    return result;","sourceCodeStart":1404,"sourceCodeEnd":1440,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/diffiehellman.ts#L1404-L1440","documentation":"A generic Error thrown by ECDH.convertKey() when op_node_ecdh_encode_pubkey fails for any reason other than an unsupported curve. It means the key bytes could not be parsed as a public key EC point on the specified curve — the buffer never became an EC_POINT, so it cannot be re-encoded to compressed/uncompressed/hybrid form.","triggerScenarios":"Passing key bytes with the wrong length for the curve (e.g. 64 raw bytes instead of a 65-byte 0x04-prefixed point for P-256), a missing or invalid prefix byte (0x02/0x03/0x04), a point that is not on the curve, or a private key / random data supplied where a public key point is expected.","commonSituations":"Peer systems send the raw X||Y coordinates without the uncompressed 0x04 header; hex strings decoded with the wrong encoding ('base64' vs 'hex'); passing a Buffer that was sliced with wrong offsets; feeding a secp256k1 key into a prime256v1 conversion.","solutions":["Verify the input length: uncompressed points are 1 + 2*fieldSize bytes (P-256: 65, P-384: 97, P-521: 133), compressed are 1 + fieldSize","Check the first byte is 0x04 (uncompressed) or 0x02/0x03 (compressed) and prepend 0x04 if the peer sent bare X||Y coordinates","Confirm inputEncoding matches how the key was produced (a hex string must be read with 'hex')","Make sure you are converting a public key, not a private scalar or a DER/PEM blob — decode those first"],"exampleFix":"// before\nconst point = Buffer.concat([x, y]); // 64 bytes, no prefix\nconst out = crypto.ECDH.convertKey(point, 'prime256v1');\n\n// after\nconst point = Buffer.concat([Buffer.from([0x04]), x, y]); // 65 bytes with 0x04 prefix\nconst out = crypto.ECDH.convertKey(point, 'prime256v1');","handlingStrategy":"validation","validationCode":"const FIELD = { prime256v1: 32, secp384r1: 48, secp521r1: 66 }[curve]!;\nconst ok = buf.length === 1 + 2 * FIELD && buf[0] === 0x04;\nif (!ok) throw new RangeError('key is not an uncompressed point for ' + curve);\nconst out = crypto.ECDH.convertKey(key, curve, inputEncoding, outputEncoding, format);","typeGuard":"const isUncompressedPoint = (b: Uint8Array, fieldSize: number): boolean =>\n  b.length === 1 + 2 * fieldSize && (b[0] === 0x04 || b[0] === 0x06 || b[0] === 0x07);","tryCatchPattern":"catch (e) { if (e.message === 'Failed to convert Buffer to EC_POINT') { /* reject peer key, re-request */ } throw e; }","preventionTips":["Agree on a single point-encoding (prefixed uncompressed) in your protocol spec","Validate key length and prefix byte at the trust boundary before any crypto op","Always pair key strings with the encoding they were produced with"],"tags":["crypto","ecdh","public-key","encoding"],"backgroundTag":"invalid-public-key-encoding","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}