VictoriaMetrics/VictoriaMetrics · error
failed to decode jwks key n: %w
Error message
failed to decode jwks key n: %w
What it means
ParseJWKs base64url-decodes the RSA modulus 'n'; if 'n' is not valid unpadded base64url the JWKS parse fails entirely. The modulus is the core of the RSA public key, so a bad 'n' means the key is unusable for verification.
Source
Thrown at lib/jwt/jwks.go:73
continue
}
switch key.Kty {
case "RSA":
if key.E == "" || key.N == "" {
return nil, fmt.Errorf("jwks key without e or n found")
}
e, err := base64.RawURLEncoding.DecodeString(key.E)
if err != nil {
return nil, fmt.Errorf("failed to decode jwks key e: %w", err)
}
exp := big.NewInt(0).SetBytes(e)
if !exp.IsInt64() || exp.Int64() < 1 {
return nil, fmt.Errorf("invalid RSA exponent")
}
n, err := base64.RawURLEncoding.DecodeString(key.N)
if err != nil {
return nil, fmt.Errorf("failed to decode jwks key n: %w", err)
}
k := &rsa.PublicKey{
E: int(exp.Int64()),
N: big.NewInt(0).SetBytes(n),
}
if slices.Contains(rsaAlgs, key.Alg) {
v, err := newVerifierRS(Algorithm(key.Alg), k)
if err != nil {
return nil, fmt.Errorf("failed to create RSA verifier for algorithm %s: %w", key.Alg, err)
}
vs = append(vs, &verifier{
Verifier: v,
key: k,
alg: key.Alg,
kid: key.Kid,View on GitHub (pinned to 5079fb58f1)
Solutions
- Re-encode the modulus with base64.RawURLEncoding (no padding, URL-safe alphabet)
- Confirm the value is the raw modulus bytes, not a PEM or hex string
- Decode it locally with base64.RawURLEncoding.DecodeString to see the exact failing character
- Fetch a fresh JWKS from the IdP's well-known endpoint
Example fix
// Go: fix encoding when generating the key // before: base64.StdEncoding.EncodeToString(n) // after base64.RawURLEncoding.EncodeToString(n)
Defensive patterns
Strategy: validation
Validate before calling
if _, err := base64.RawURLEncoding.DecodeString(jwk.N); err != nil {
return fmt.Errorf("jwk %s: invalid n field: %w", jwk.Kid, err)
} Type guard
func validB64URL(s string) bool {
_, err := base64.RawURLEncoding.DecodeString(s)
return err == nil
} Try / catch
keys, err := ParseJWKs(raw)
if err != nil {
var decErr error
if strings.Contains(err.Error(), "failed to decode jwks key n") { decErr = err }
if decErr != nil { logger.Errorf("bad modulus in JWKS: %v", decErr) }
return err
} Prevention
- Encode moduli with base64.RawURLEncoding, never StdEncoding
- Verify JWKS JSON isn't line-wrapped or re-encoded by proxies
- Re-fetch from the IdP's /.well-known/jwks.json when in doubt
- Add a JWKS fixture validation unit test
When it happens
Trigger: A JWKS RSA key with 'n' containing '+' or '/', '=' padding, whitespace, or other characters rejected by base64.RawURLEncoding.DecodeString.
Common situations: Standard base64 used instead of base64url when generating fixture keys; line-wrapped PEM data pasted into 'n'; IdP or proxy mangling the JWKS JSON.
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 decode jwks key e: %w
- invalid RSA exponent
- failed to create RSA verifier for algorithm %s: %w
- jwks key with use=sig has unsupported alg %s; supported %v,
- failed to decode jwks key x: %w
AI-assisted analysis of VictoriaMetrics/VictoriaMetrics@5079fb58f1 (2026-09-03).
Data as JSON: /api/errors/8bea7e15b4f9175e.
Report an issue: GitHub.