kataras/iris · critical
err
Error message
err
What it means
Signer.WithEncryption enables AES-GCM payload encryption using golang-jwt's GCM constructor. If the key is not a valid AES key size (16, 24, or 32 bytes) the constructor returns an error and the Signer panics immediately, since encryption misconfiguration must be caught before serving.
Source
Thrown at middleware/jwt/signer.go:61
s := &Signer{
Alg: signatureAlg,
Key: signatureKey,
MaxAge: maxAge,
}
if maxAge > 0 {
s.Options = []SignOption{MaxAge(maxAge)}
}
return s
}
// WithEncryption enables AES-GCM payload-only decryption.
func (s *Signer) WithEncryption(key, additionalData []byte) *Signer {
encrypt, _, err := jwt.GCM(key, additionalData)
if err != nil {
panic(err) // important error before serve, stop everything.
}
s.Encrypt = encrypt
return s
}
// Sign generates a new token based on the given "claims" which is valid up to "s.MaxAge".
func (s *Signer) Sign(claims any, opts ...SignOption) ([]byte, error) {
if len(opts) > 0 {
opts = append(opts, s.Options...)
} else {
opts = s.Options
}
return SignEncrypted(s.Alg, s.Key, s.Encrypt, claims, opts...)
}
// NewTokenPair accepts the access and refresh claims plus the life time duration for the refresh tokenView on GitHub (pinned to 7bedaf55a0)
Solutions
- Make the key exactly 32 bytes (AES-256): sha256.Sum256([]byte(passphrase)) or a 32-byte random key.
- If loading from env, decode it: base64.StdEncoding.DecodeString or hex.DecodeString, then verify len(key) is 16/24/32 before calling WithEncryption.
- Generate a proper key with crypto/rand: make([]byte, 32); rand.Read(key).
Example fix
// before
signer.WithEncryption([]byte(os.Getenv("JWT_KEY")), nil) // wrong length
// after
key, _ := hex.DecodeString(os.Getenv("JWT_KEY"))
if n := len(key); n != 16 && n != 24 && n != 32 {
log.Fatalf("jwt gcm key must be 16/24/32 bytes, got %d", n)
}
signer.WithEncryption(key, nil) Defensive patterns
Strategy: validation
Validate before calling
func validateGCMKey(key []byte) error {
switch len(key) {
case 16, 24, 32:
return nil
}
return fmt.Errorf("AES-GCM key must be 16, 24, or 32 bytes, got %d", len(key))
} Try / catch
defer func() {
if r := recover(); r != nil {
log.Fatalf("jwt encryption setup failed: %v", r)
}
}()
s.WithEncryption(key, aad) Prevention
- Generate keys with crypto/rand at exactly 32 bytes and store them encoded (base64/hex).
- Decode keys before use and assert length at config-load time.
- Never pass passphrase strings directly as AES keys.
When it happens
Trigger: Calling signer.WithEncryption(key, additionalData) with a key whose length is not 16, 24, or 32 bytes — e.g. a short passphrase, an empty slice, or a 33-byte key.
Common situations: Reading the key from an env var that is unset or a raw passphrase instead of a decoded base64/hex key; truncating a hex string; key generated with a non-standard length.
Related errors
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/56c58fa22baf7ed1.
Report an issue: GitHub.