micro/go-micro · error
ErrInvalidToken
ErrInvalidToken
Error message
invalid token provided
What it means
ErrInvalidToken is the auth package's sentinel for a token that is not valid — missing, malformed, expired, or failing verification. Inspect and TokenFromMetadata return it, so callers should match with errors.Is to detect bad credentials.
Source
Thrown at auth/auth.go:21
import (
"context"
"errors"
"time"
)
const (
// BearerScheme used for Authorization header.
BearerScheme = "Bearer "
// ScopePublic is the scope applied to a rule to allow access to the public.
ScopePublic = ""
// ScopeAccount is the scope applied to a rule to limit to users with any valid account.
ScopeAccount = "*"
)
var (
// ErrInvalidToken is when the token provided is not valid.
ErrInvalidToken = errors.New("invalid token provided")
// ErrForbidden is when a user does not have the necessary scope to access a resource.
ErrForbidden = errors.New("resource forbidden")
)
// Auth provides authentication and authorization.
type Auth interface {
// Init the auth
Init(opts ...Option)
// Options set for auth
Options() Options
// Generate a new account
Generate(id string, opts ...GenerateOption) (*Account, error)
// Inspect a token
Inspect(token string) (*Account, error)
// Token generated using refresh token or credentials
Token(opts ...TokenOption) (*Token, error)
// String returns the name of the implementation
String() stringView on GitHub (pinned to 24529f1404)
Solutions
- Ensure the client sends the token correctly (Authorization metadata/header present and non-empty)
- Refresh or reissue the token — if expired, obtain a new one via login/refresh flow
- Verify the auth service's signing key matches the issuer's key (no key-rotation mismatch)
- Validate token format (correct scheme prefix, three-part JWT) before sending
Example fix
// before
md := metadata.New(nil) // no token attached
acc, err := auth Inspect(ctx, md) // ErrInvalidToken
// after
md := metadata.Pairs("authorization", "Bearer "+token)
acc, err := a.Inspect(ctx, md)
if errors.Is(err, auth.ErrInvalidToken) {
token = refreshToken() // obtain a fresh token
} Defensive patterns
Strategy: type-guard
Validate before calling
if token == "" {
return auth.ErrInvalidToken
}
parsed, err := jwt.Parse(token, keyFn)
if err != nil || !parsed.Valid {
return auth.ErrInvalidToken
} Type guard
func hasToken(md metadata.MD) bool {
vals := md.Get("authorization")
return len(vals) > 0 && strings.TrimSpace(vals[0]) != ""
} Try / catch
acc, err := a.Inspect(ctx, md)
if errors.Is(err, auth.ErrInvalidToken) {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
if errors.Is(err, auth.ErrForbidden) {
http.Error(w, "forbidden", http.StatusForbidden)
return
} Prevention
- Use errors.Is(err, auth.ErrInvalidToken) rather than string comparison
- Refresh tokens proactively before expiry (e.g. on 401, retry once with a fresh token)
- Keep signing keys in sync between issuer and verifier across key rotations
- Validate the Authorization header is present and well-formed client-side before sending
When it happens
Trigger: Calling auth Inspect or TokenFromMetadata with an empty metadata map, a missing/blank Authorization token, a token signed by the wrong key, or an expired/revoked token.
Common situations: Client not sending the Authorization header/metadata; JWT expiry on long-lived sessions; rotating signing keys so old tokens no longer verify; copying a token from the wrong environment; clock skew invalidating not-yet-valid or just-expired tokens.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- ErrNotFound
- ErrInvalidToken
- API error (%s): %s
- agent: StreamAsk unsupported by implementation
- agent: ResumeStreamAsk unsupported by implementation
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/08953a02799429ed.
Report an issue: GitHub.