{"record":{"id":"0e0bf934ee8231ca","repo":"grafana/k6","slug":"invalid-ec-jwk-key-w","errorCode":null,"errorMessage":"invalid EC JWK key: %w","messagePattern":"invalid EC JWK key: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/webcrypto/jwk.go","lineNumber":228,"sourceCode":"\n\texported.Set(\"x\", base64URLEncode(x.Bytes()))\n\texported.Set(\"y\", base64URLEncode(y.Bytes()))\n\n\tif d != nil {\n\t\texported.Set(\"d\", encodeCurveBigInt(d, curveBits))\n\t}\n\n\treturn exported, nil\n}\n\nfunc importECDSAJWK(_ EllipticCurveKind, jsonKeyData []byte) (any, CryptoKeyType, error) {\n\tvar jwkKey ecJWK\n\tif err := json.Unmarshal(jsonKeyData, &jwkKey); err != nil {\n\t\treturn nil, UnknownCryptoKeyType, fmt.Errorf(\"failed to parse input as EC JWK key: %w\", err)\n\t}\n\n\tif err := jwkKey.validate(); err != nil {\n\t\treturn nil, UnknownCryptoKeyType, fmt.Errorf(\"invalid EC JWK key: %w\", err)\n\t}\n\n\tcrv, err := pickEllipticCurve(jwkKey.Crv)\n\tif err != nil {\n\t\treturn nil, UnknownCryptoKeyType, fmt.Errorf(\"failed to parse elliptic curve: %w\", err)\n\t}\n\n\tx, err := base64URLDecode(jwkKey.X)\n\tif err != nil {\n\t\treturn nil, UnknownCryptoKeyType, fmt.Errorf(\"failed to decode X coordinate: %w\", err)\n\t}\n\n\ty, err := base64URLDecode(jwkKey.Y)\n\tif err != nil {\n\t\treturn nil, UnknownCryptoKeyType, fmt.Errorf(\"failed to decode Y coordinate: %w\", err)\n\t}\n\n\tpk := &ecdsa.PublicKey{","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/webcrypto/jwk.go#L210-L246","documentation":"After JSON parsing, the EC JWK is checked by ecJWK.validate(): kty must equal 'EC' (exact case) and crv, x and y must be non-empty strings. This error wraps any of those validation failures and is returned from importKey('jwk', ...) for ECDSA keys. The wrapped message names the actual problem ('invalid key type: ...', 'curve is required', 'coordinate X is required', 'coordinate Y is required').","triggerScenarios":"importKey('jwk', jwk, {name:'ECDSA',...}) with kty not exactly 'EC' (e.g. 'ec', 'RSA', 'oct'); a JWK with crv, x or y missing or empty; a symmetric or RSA JWK mistakenly fed to the ECDSA importer.","commonSituations":"Mixing up key families (passing an RSA JWK to an ECDSA algorithm object); case-normalized kty values from case-insensitive systems; partial JWKs copied from documentation or JWT headers (which lack x/y).","solutions":["Set kty to exactly 'EC'","Include non-empty crv, x and y string fields","Match the JWK's kty with the algorithm passed to importKey (EC JWK for ECDSA/ECDH, RSA JWK for RSA algorithms)","Read the wrapped message after 'invalid EC JWK key:' to see which field failed"],"exampleFix":"// before\nconst jwk = { kty: 'ec', crv: 'P-256', x: 'abc...' }; // wrong case + missing y\nconst key = await crypto.subtle.importKey('jwk', jwk, alg, true, ['verify']);\n// after\nconst jwk = { kty: 'EC', crv: 'P-256', x: 'abc...', y: 'def...' };","handlingStrategy":"validation","validationCode":"function isValidEcJwk(jwk) {\n  return jwk && typeof jwk === 'object' &&\n    jwk.kty === 'EC' &&\n    typeof jwk.crv === 'string' && jwk.crv !== '' &&\n    typeof jwk.x === 'string' && jwk.x !== '' &&\n    typeof jwk.y === 'string' && jwk.y !== '';\n}\nif (!isValidEcJwk(jwk)) throw new Error('EC JWK must have kty=\"EC\" and non-empty crv, x, y');","typeGuard":"function isEcJwk(jwk) {\n  return !!jwk && typeof jwk === 'object' &&\n    jwk.kty === 'EC' &&\n    typeof jwk.crv === 'string' && jwk.crv.length > 0 &&\n    typeof jwk.x === 'string' && jwk.x.length > 0 &&\n    typeof jwk.y === 'string' && jwk.y.length > 0;\n}","tryCatchPattern":"try {\n  key = await crypto.subtle.importKey('jwk', jwk, alg, true, usages);\n} catch (e) {\n  if (e.message.includes('invalid EC JWK key')) console.error('JWK shape invalid:', jwk.kty, jwk.crv, !!jwk.x, !!jwk.y);\n  throw e;\n}","preventionTips":["Validate kty/crv/x/y presence in fixtures before the test run starts","Use exact 'EC' casing","Match JWK family to the algorithm object passed to importKey"],"tags":["webcrypto","jwk","import","ecdsa","validation","k6"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}