grafana/k6 · error
failed to parse input as RSA JWK key: %w
Error message
failed to parse input as RSA JWK key: %w
What it means
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.
Source
Thrown at internal/js/modules/k6/webcrypto/jwk.go:327
return fmt.Errorf("invalid key type: %s", jwk.Kty)
}
if jwk.N == "" {
return errors.New("modulus (n) is required")
}
if jwk.E == "" {
return errors.New("exponent (e) is required")
}
// TODO: consider validating the other fields in future
return nil
}
func importRSAJWK(jsonKeyData []byte) (any, CryptoKeyType, int, error) {
var jwk rsaJWK
if err := json.Unmarshal(jsonKeyData, &jwk); err != nil {
return nil, UnknownCryptoKeyType, 0, fmt.Errorf("failed to parse input as RSA JWK key: %w", err)
}
if err := jwk.validate(); err != nil {
return nil, UnknownCryptoKeyType, 0, fmt.Errorf("invalid RSA JWK key: %w", err)
}
// decode the various key components
nBytes, err := base64URLDecode(jwk.N)
if err != nil {
return nil, UnknownCryptoKeyType, 0, fmt.Errorf("failed to decode modulus: %w", err)
}
eBytes, err := base64URLDecode(jwk.E)
if err != nil {
return nil, UnknownCryptoKeyType, 0, fmt.Errorf("failed to decode exponent: %w", err)
}
// convert exponent to an integer
eInt := new(big.Int).SetBytes(eBytes).Int64()View on GitHub (pinned to 93accf6570)
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
Example fix
// before
const jwk = { kty: 'RSA', n: '...', e: 65537 }; // exponent as number
// after
const jwk = { kty: 'RSA', n: '...', e: 'AQAB' }; // base64url-encoded exponent Defensive patterns
Strategy: validation
Validate before calling
const RSA_STR_FIELDS = ['kty','n','e','d','p','q','dp','dq','qi'];
function rsaFieldsAreStrings(jwk) {
return jwk && typeof jwk === 'object' && !Array.isArray(jwk) &&
RSA_STR_FIELDS.every(f => jwk[f] === undefined || typeof jwk[f] === 'string');
}
if (!rsaFieldsAreStrings(jwk)) throw new Error('RSA JWK fields must be strings; pass an object, not JSON text'); Type guard
function isRsaJwkShape(v) {
return v !== null && typeof v === 'object' && !Array.isArray(v) &&
['kty','n','e'].every(f => typeof v[f] === 'string') &&
['d','p','q','dp','dq','qi'].every(f => v[f] === undefined || typeof v[f] === 'string');
} Try / catch
try {
key = await crypto.subtle.importKey('jwk', jwk, rsaAlg, true, usages);
} catch (e) {
if (e.message.includes('failed to parse input as RSA JWK key')) {
throw new Error('pass a plain JWK object with string fields (e.g. e as "AQAB", not 65537)');
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse input as EC JWK key: %w
- invalid RSA JWK key: %w
- failed to decode modulus: %w
- failed to decode exponent: %w
- failed to decode private exponent: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/35dfb1c766da18ba.
Report an issue: GitHub.