{"record":{"id":"5400c9963d38c036","repo":"denoland/deno","slug":"err-crypto-invalid-jwk","errorCode":"ERR_CRYPTO_INVALID_JWK","errorMessage":"Invalid JWK","messagePattern":"Invalid JWK","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/keys.ts","lineNumber":277,"sourceCode":"    );\n    validateString(key.x, \"key.x\");\n\n    if (!isPublic) {\n      validateString(key.d, \"key.d\");\n    }\n\n    let keyData;\n    if (isPublic) {\n      keyData = Buffer.from(key.x, \"base64\");\n    } else {\n      keyData = Buffer.from(key.d, \"base64\");\n    }\n\n    switch (key.crv) {\n      case \"Ed25519\":\n      case \"X25519\":\n        if (TypedArrayPrototypeGetByteLength(keyData) !== 32) {\n          throw new ERR_CRYPTO_INVALID_JWK();\n        }\n        break;\n      case \"Ed448\":\n        if (TypedArrayPrototypeGetByteLength(keyData) !== 57) {\n          throw new ERR_CRYPTO_INVALID_JWK();\n        }\n        break;\n      case \"X448\":\n        if (TypedArrayPrototypeGetByteLength(keyData) !== 56) {\n          throw new ERR_CRYPTO_INVALID_JWK();\n        }\n        break;\n    }\n\n    return op_node_create_ed_raw(key.crv, keyData, isPublic);\n  }\n\n  if (key.kty === \"EC\") {","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/keys.ts#L259-L295","documentation":"When importing an OKP JWK (options.format 'jwk') via createPublicKey/createPrivateKey, the base64-decoded x (public) or d (private) component must have the exact byte length of the curve: 32 for Ed25519/X25519, 57 for Ed448, 56 for X448. Any other length throws ERR_CRYPTO_INVALID_JWK ('Invalid JWK').","triggerScenarios":"createPrivateKey({ key: { kty: 'OKP', crv: 'Ed25519', x: '...', d: 'short-or-corrupt-base64' }, format: 'jwk' }) — truncated key material, a key generated for a different curve than the declared crv, or corrupted base64 that decodes to the wrong byte count.","commonSituations":"Hand-editing or truncating JWKs; transport through env vars/JSON that clips long values; generating an X448 key but declaring Ed448 (or vice versa); whitespace/padding damage that changes the decoded length.","solutions":["Regenerate the JWK from a trusted source (WebCrypto subtle.exportKey('jwk', ...) or crypto key export) instead of hand-writing it","Before importing, base64-decode x/d and check the byte length matches the curve (32/57/56)","Make sure the crv field matches the key material actually embedded in the JWK"],"exampleFix":"// before\nconst jwk = { kty: 'OKP', crv: 'Ed448', x: x32Bytes, d: d32Bytes }; // wrong curve lengths\ncrypto.createPrivateKey({ key: jwk, format: 'jwk' });\n// after\nconst jwk = { kty: 'OKP', crv: 'Ed448', x: x57Bytes, d: d57Bytes };\ncrypto.createPrivateKey({ key: jwk, format: 'jwk' });","handlingStrategy":"validation","validationCode":"const OKP_LENGTHS = { Ed25519: 32, X25519: 32, Ed448: 57, X448: 56 };\nfunction isValidOkpJwk(jwk) {\n  if (jwk.kty !== 'OKP' || !(jwk.crv in OKP_LENGTHS)) return false;\n  const material = jwk.d ?? jwk.x;\n  return Buffer.from(material, 'base64').length === OKP_LENGTHS[jwk.crv];\n}\nif (!isValidOkpJwk(jwk)) throw new Error('JWK does not match its curve length');\ncrypto.createPrivateKey({ key: jwk, format: 'jwk' });","typeGuard":"function isOkpJwkWithValidLength(jwk) {\n  const lens = { Ed25519: 32, X25519: 32, Ed448: 57, X448: 56 };\n  return jwk?.kty === 'OKP' && jwk.crv in lens &&\n    Buffer.from(jwk.d ?? jwk.x, 'base64').byteLength === lens[jwk.crv];\n}","tryCatchPattern":"try {\n  return crypto.createPrivateKey({ key: jwk, format: 'jwk' });\n} catch (e) {\n  if (e.code === 'ERR_CRYPTO_INVALID_JWK') throw new Error('JWK key material length does not match crv; re-export the key');\n  throw e;\n}","preventionTips":["Produce JWKs only via standard exports, never by hand","Validate x/d byte lengths against the curve before importing","Beware transports that trim or corrupt long base64 strings"],"tags":["crypto","jwk","ed25519","node-compat"],"backgroundTag":"invalid-jwk","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}