kataras/iris · error

access: %w

Error message

access: %w

What it means

The internal sign helper returns 'access: %w' when s.keys.SignToken(KIDAccess, ...) fails to create the access token. This wraps the keystore error so callers of Signin/Refresh see an 'access: ...' prefixed cause. The refresh token signing follows separately with its own wrap.

Source

Thrown at auth/auth.go:296

	if refreshStdClaims.IssuedAt == 0 {
		refreshStdClaims.IssuedAt = iat
	}

	if refreshStdClaims.ID == "" {
		refreshStdClaims.ID = uuid.NewString()
	}

	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.

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Check the wrapped cause with errors.Unwrap/%v to see the keystore error
  2. Ensure the KIDAccess key exists and is valid in the configured key set
  3. Re-sync configuration after key rotation so the current KID is used
  4. Fail fast: sign a test token during app startup

Example fix

// before
access, _, err := a.Signin(ctx, user, pass) // "access: kid not found"
// after
keys.Add(KIDAccess, privateKey) // register the access signing key
access, _, err := a.Signin(ctx, user, pass)
Defensive patterns

Strategy: validation

Validate before calling

if _, err := keys.Get(KIDAccess); err != nil {
    return fmt.Errorf("access signing key unavailable: %w", err)
}

Type guard

func isAccessTokenSignErr(err error) bool { return err != nil && strings.HasPrefix(err.Error(), "access: ") }

Try / catch

if _, _, err := a.Signin(ctx, user, pass); err != nil {
    if strings.HasPrefix(err.Error(), "access: ") {
        cause := errors.Unwrap(err)
        log.Printf("access token signing: %v", cause)
        return http.StatusInternalServerError
    }
    return http.StatusUnauthorized
}

Prevention

When it happens

Trigger: SignToken for the KIDAccess key failing — missing key ID in the keystore, invalid private key, or a claims-encoding error during token generation, triggered from either Signin or Refresh.

Common situations: Access key not provisioned/rotated out of the keystore; corrupted or wrong-format PEM key; keyset updated (key rotation) while old KID is still referenced in configuration.

Related errors


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/f0eb370ce9617c24. Report an issue: GitHub.