kataras/iris · error
refresh: %w
Error message
refresh: %w
What it means
This error wraps any failure that occurs while signing the refresh token inside Auth.sign(). It only fires when refresh tokens are enabled, i.e. the configuration's Keys contain a KIDRefresh key. The underlying error comes from the JWT signer (Key.SignToken), typically a bad or unusable key.
Source
Thrown at auth/auth.go:303
}
if refreshStdClaims.OriginID == "" {
// keep a reference of the access token the refresh token is created,
// if that access token is invalidated then
// its refresh token should be too so the user can force-login.
refreshStdClaims.OriginID = accessStdClaims.ID
}
accessToken, err := s.keys.SignToken(KIDAccess, t, accessStdClaims)
if err != nil {
return nil, nil, fmt.Errorf("access: %w", err)
}
var refreshToken []byte
if s.refreshEnabled {
refreshToken, err = s.keys.SignToken(KIDRefresh, t, refreshStdClaims)
if err != nil {
return nil, nil, fmt.Errorf("refresh: %w", err)
}
}
return accessToken, refreshToken, nil
}
// SignHandler generates and sends a pair of access and refresh token to the client
// as JSON body of `SigninResponse` and cookie (if cookie setting was provided).
// See `Signin` method for more.
func (s *Auth[T]) SigninHandler(ctx *context.Context) {
// No, let the developer decide it based on a middleware, e.g. iris.LimitRequestBodySize.
// ctx.SetMaxRequestBodySize(s.maxRequestBodySize)
var (
req SigninRequest
err error
)
View on GitHub (pinned to 7bedaf55a0)
Solutions
- Inspect the wrapped %w error to find the exact SignToken failure
- Verify the KIDRefresh key material is valid and matches the configured algorithm
- Confirm the KIDRefresh key type (HMAC secret vs RSA/ECDSA private key) matches c.Keys configuration
- If refresh tokens are not needed, remove KIDRefresh from Keys so the refresh path is skipped
Example fix
// before
Keys: map[string]jwt.Key{ "access": []byte("short"), "refresh": "" }
// after
Keys: map[string]jwt.Key{ "access": []byte(longRandomSecret), "refresh": []byte(anotherLongRandomSecret) } Defensive patterns
Strategy: try-catch
Validate before calling
for kid := range map[string][]byte{"access": accessKey, "refresh": refreshKey} {
if len(k[kid]) == 0 { return fmt.Errorf("empty key material for %s", kid) }
} Try / catch
access, refresh, err := auth.Signin(ctx, username, password)
if err != nil {
var cfgErr interface{ Unwrap() error }
if errors.Is(err, jwt.ErrKeyMismatch) { /* fix key config */ }
return fmt.Errorf("signin failed: %w", err)
} Prevention
- Validate key material length and type at startup before serving traffic
- Only add KIDRefresh to Keys if you actually intend to use refresh flow
- Add a startup smoke test that calls Signin in a staging environment
- Keep signing secrets in a secret manager instead of hand-edited config files
When it happens
Trigger: s.refreshEnabled is true (a KIDRefresh key was configured) and s.keys.SignToken(KIDRefresh, t, refreshStdClaims) returns an error — e.g. the refresh key bytes are invalid, the algorithm and key type mismatch, or the key store fails to produce a signed token. Reached via Signin or Refresh.
Common situations: A KIDRefresh entry was added to config.Keys with malformed or too-short key material, an RSA key supplied where HMAC is expected, or a key file/env value that fails to parse during SignToken.
Related errors
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/a95bba9abd00932e.
Report an issue: GitHub.