{"record":{"id":"35dfb1c766da18ba","repo":"grafana/k6","slug":"failed-to-parse-input-as-rsa-jwk-key-w","errorCode":null,"errorMessage":"failed to parse input as RSA JWK key: %w","messagePattern":"failed to parse input as RSA JWK key: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/webcrypto/jwk.go","lineNumber":327,"sourceCode":"\t\treturn fmt.Errorf(\"invalid key type: %s\", jwk.Kty)\n\t}\n\n\tif jwk.N == \"\" {\n\t\treturn errors.New(\"modulus (n) is required\")\n\t}\n\n\tif jwk.E == \"\" {\n\t\treturn errors.New(\"exponent (e) is required\")\n\t}\n\n\t// TODO: consider validating the other fields in future\n\treturn nil\n}\n\nfunc importRSAJWK(jsonKeyData []byte) (any, CryptoKeyType, int, error) {\n\tvar jwk rsaJWK\n\tif err := json.Unmarshal(jsonKeyData, &jwk); err != nil {\n\t\treturn nil, UnknownCryptoKeyType, 0, fmt.Errorf(\"failed to parse input as RSA JWK key: %w\", err)\n\t}\n\n\tif err := jwk.validate(); err != nil {\n\t\treturn nil, UnknownCryptoKeyType, 0, fmt.Errorf(\"invalid RSA JWK key: %w\", err)\n\t}\n\n\t// decode the various key components\n\tnBytes, err := base64URLDecode(jwk.N)\n\tif err != nil {\n\t\treturn nil, UnknownCryptoKeyType, 0, fmt.Errorf(\"failed to decode modulus: %w\", err)\n\t}\n\teBytes, err := base64URLDecode(jwk.E)\n\tif err != nil {\n\t\treturn nil, UnknownCryptoKeyType, 0, fmt.Errorf(\"failed to decode exponent: %w\", err)\n\t}\n\n\t// convert exponent to an integer\n\teInt := new(big.Int).SetBytes(eBytes).Int64()","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/webcrypto/jwk.go#L309-L345","documentation":"importRSAJWK starts by unmarshaling the JWK bytes into the rsaJWK struct (kty, n, e, d, p, q, dp, dq, qi — all expected as JSON strings). This error means that unmarshaling failed, with Go's specific 'json: cannot unmarshal ...' detail in the wrapped %w. Since k6 re-serializes the JS object before this step, failures come from fields having the wrong JSON type.","triggerScenarios":"importKey('jwk', keyData, rsaAlg, ...) where keyData is a JSON string rather than an object, or where n/e/d/p/q/dp/dq/qi are numbers, booleans, arrays or nested objects instead of strings.","commonSituations":"Passing JSON.stringify-ed JWKs; JWKs from services that emit the exponent as a number (e.g. 65537) instead of the string 'AQAB'; script-generated JWKs with byte arrays.","solutions":["Pass a plain JavaScript object, not a JSON string","Encode e as a base64url string ('AQAB' for 65537), not a number","Keep all RSA fields as strings","Inspect the wrapped message to find the exact field and type mismatch"],"exampleFix":"// before\nconst jwk = { kty: 'RSA', n: '...', e: 65537 }; // exponent as number\n// after\nconst jwk = { kty: 'RSA', n: '...', e: 'AQAB' }; // base64url-encoded exponent","handlingStrategy":"validation","validationCode":"const RSA_STR_FIELDS = ['kty','n','e','d','p','q','dp','dq','qi'];\nfunction rsaFieldsAreStrings(jwk) {\n  return jwk && typeof jwk === 'object' && !Array.isArray(jwk) &&\n    RSA_STR_FIELDS.every(f => jwk[f] === undefined || typeof jwk[f] === 'string');\n}\nif (!rsaFieldsAreStrings(jwk)) throw new Error('RSA JWK fields must be strings; pass an object, not JSON text');","typeGuard":"function isRsaJwkShape(v) {\n  return v !== null && typeof v === 'object' && !Array.isArray(v) &&\n    ['kty','n','e'].every(f => typeof v[f] === 'string') &&\n    ['d','p','q','dp','dq','qi'].every(f => v[f] === undefined || typeof v[f] === 'string');\n}","tryCatchPattern":"try {\n  key = await crypto.subtle.importKey('jwk', jwk, rsaAlg, true, usages);\n} catch (e) {\n  if (e.message.includes('failed to parse input as RSA JWK key')) {\n    throw new Error('pass a plain JWK object with string fields (e.g. e as \"AQAB\", not 65537)');\n  }\n  throw e;\n}","preventionTips":["Never pass JSON.stringify-ed JWKs to importKey","Encode e as base64url string 'AQAB', not the number 65537","Validate field types when loading JWKs from external services"],"tags":["webcrypto","jwk","import","rsa","json","k6"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}