kataras/iris · critical
err
Error message
err
What it means
Verifier.WithDecryption enables AES-GCM payload-only decryption via jwt.GCM. It panics when jwt.GCM returns an error, which happens when the key length is not a valid AES size (16, 24, or 32 bytes). Like WithEncryption, this is fail-fast at construction time.
Source
Thrown at middleware/jwt/verifier.go:112
}
}
return &Verifier{
Alg: signatureAlg,
Key: signatureKey,
Extractors: []TokenExtractor{FromHeader, FromQuery},
ErrorHandler: func(ctx *context.Context, err error) {
ctx.StopWithError(401, context.PrivateError(err))
},
Validators: validators,
}
}
// WithDecryption enables AES-GCM payload-only encryption.
func (v *Verifier) WithDecryption(key, additionalData []byte) *Verifier {
_, decrypt, err := jwt.GCM(key, additionalData)
if err != nil {
panic(err) // important error before serve, stop everything.
}
v.Decrypt = decrypt
return v
}
// WithDefaultBlocklist attaches an in-memory blocklist storage
// to invalidate tokens through server-side.
// To invalidate a token simply call the Context.Logout method.
func (v *Verifier) WithDefaultBlocklist() *Verifier {
v.Blocklist = jwt.NewBlocklist(30 * time.Minute)
return v
}
func (v *Verifier) invalidate(ctx *context.Context) {
if verifiedToken := GetVerifiedToken(ctx); verifiedToken != nil {
v.Blocklist.InvalidateToken(verifiedToken.Token, verifiedToken.StandardClaims)
ctx.Values().Remove(claimsContextKey)View on GitHub (pinned to 7bedaf55a0)
Solutions
- Validate key length (16/24/32 bytes) before calling WithDecryption and fail with a clear log message.
- Decode the key from its stored encoding (base64/hex) rather than passing the encoded string bytes.
- Ensure both sides derive the identical key material (same env var, same decode step).
Example fix
// before
v.WithDecryption([]byte(cfg.Key), nil) // cfg.Key is base64 text, wrong length
// after
key, err := base64.StdEncoding.DecodeString(cfg.Key)
if err != nil || (len(key) != 16 && len(key) != 24 && len(key) != 32) {
log.Fatal("invalid jwt decryption key")
}
v.WithDecryption(key, nil) Defensive patterns
Strategy: validation
Validate before calling
key, err := base64.StdEncoding.DecodeString(os.Getenv("JWT_DEC_KEY"))
if err != nil {
log.Fatalf("bad jwt key encoding: %v", err)
}
if n := len(key); n != 16 && n != 24 && n != 32 {
log.Fatalf("jwt key must be 16/24/32 bytes, got %d", n)
} Try / catch
defer func() {
if r := recover(); r != nil {
log.Fatalf("jwt decryption setup failed: %v", r)
}
}()
v.WithDecryption(key, aad) Prevention
- Share one key-loading helper between encryptor and verifier so both use identical bytes.
- Strip whitespace/quotes from env-provided keys before decoding.
- Assert key equality (or length) at startup with a paired encrypt/decrypt self-test.
When it happens
Trigger: Calling verifier.WithDecryption(key, additionalData) with a key that is empty, too short (e.g. raw passphrase bytes), or otherwise not 16/24/32 bytes. The key must also be the same one used for encryption.
Common situations: Mismatched env configuration between services (encryptor got the real 32-byte key, verifier got a truncated copy); key stored with quotes/newlines included; forgetting to base64-decode before passing.
Related errors
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/7a70a18eaed8f613.
Report an issue: GitHub.