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 token

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Make the key exactly 32 bytes (AES-256): sha256.Sum256([]byte(passphrase)) or a 32-byte random key.
  2. If loading from env, decode it: base64.StdEncoding.DecodeString or hex.DecodeString, then verify len(key) is 16/24/32 before calling WithEncryption.
  3. 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

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.