micro/go-micro · warning

invalid token format, expected 'Bearer <token>'

Error message

invalid token format, expected 'Bearer <token>'

What it means

ErrInvalidToken is returned when the Authorization metadata value exists but does not start with 'Bearer ', or the token after the prefix is empty. The library strictly expects the 'Bearer <token>' format per RFC 6750.

Source

Thrown at wrapper/auth/metadata.go:22

	"errors"
	"strings"

	"go-micro.dev/v6/auth"
	"go-micro.dev/v6/metadata"
)

const (
	// MetadataKeyAuthorization is the key for the Authorization header in metadata
	MetadataKeyAuthorization = "Authorization"
	// BearerPrefix is the prefix for Bearer tokens
	BearerPrefix = "Bearer "
)

var (
	// ErrMissingToken is returned when no authorization token is found in metadata
	ErrMissingToken = errors.New("missing authorization token in metadata")
	// ErrInvalidToken is returned when the token format is invalid
	ErrInvalidToken = errors.New("invalid token format, expected 'Bearer <token>'")
)

// TokenFromMetadata extracts the Bearer token from request metadata.
// Returns the token string without the "Bearer " prefix, or an error if not found.
func TokenFromMetadata(md metadata.Metadata) (string, error) {
	// Check for Authorization header
	authHeader, ok := md.Get(MetadataKeyAuthorization)
	if !ok {
		// Also check lowercase version
		authHeader, ok = md.Get(strings.ToLower(MetadataKeyAuthorization))
		if !ok {
			return "", ErrMissingToken
		}
	}

	// Verify Bearer prefix
	if !strings.HasPrefix(authHeader, BearerPrefix) {
		return "", ErrInvalidToken

View on GitHub (pinned to 24529f1404)

Solutions

  1. Format the header exactly as 'Bearer '+token using auth.TokenToMetadata
  2. Ensure the token itself is non-empty before setting metadata
  3. If a peer sends a different scheme, normalize on the client or relax/branch the server check before calling TokenFromMetadata
  4. Check for accidental lowercasing of the 'Bearer ' prefix in proxy layers

Example fix

// before
md.Set("Authorization", token) // raw token
// after
md := auth.TokenToMetadata(metadata.Metadata{}, token) // sets "Bearer <token>"
Defensive patterns

Strategy: validation

Validate before calling

func validBearerHeader(md metadata.Metadata) bool {
	v, ok := md.Get("Authorization")
	return ok && strings.HasPrefix(v, "Bearer ") && len(strings.TrimPrefix(v, "Bearer ")) > 0
}
// if !validBearerHeader(md) { md = auth.TokenToMetadata(md, token) }

Type guard

func isInvalidToken(err error) bool { return errors.Is(err, auth.ErrInvalidToken) }

Try / catch

token, err := auth.TokenFromMetadata(md)
if errors.Is(err, auth.ErrInvalidToken) {
	// client sent a malformed Authorization value; return 401 with hint
	return errors.New("unauthorized: expected 'Bearer <token>'")
}

Prevention

When it happens

Trigger: TokenFromMetadata receives md with Authorization set to a raw token without the 'Bearer ' prefix (e.g. just 'eyJhbG...'), 'Basic xxx', or 'Bearer ' with no token; hand-rolled header construction bypassing TokenToMetadata.

Common situations: Tokens copied from other systems that use raw values; lowercasing the header to 'bearer token' (case-sensitive prefix check fails); frontends sending 'Token ' or no scheme; empty token variables formatted anyway.

Understand the failure class

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/b3882f50feaeeb41. Report an issue: GitHub.