micro/go-micro · warning

missing authorization token in metadata

Error message

missing authorization token in metadata

What it means

ErrMissingToken is returned by TokenFromMetadata (and via AccountFromMetadata) when the request metadata contains no Authorization header — checked under both 'Authorization' and 'authorization' keys. The library cannot authenticate the caller because no credential was forwarded.

Source

Thrown at wrapper/auth/metadata.go:20

import (
	"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

View on GitHub (pinned to 24529f1404)

Solutions

  1. Set the header before sending: use auth.TokenToMetadata(md, token) or the auth client wrapper so Authorization: Bearer <token> is attached
  2. Verify intermediate services/proxies propagate metadata keys unchanged
  3. Call TokenToMetadata with a non-empty token in tests/tools that exercise protected endpoints

Example fix

// before
res, err := client.Call(ctx, req) // no auth metadata
// after
md := auth.TokenToMetadata(metadata.Metadata{}, token)
ctx = metadata.NewContext(ctx, md)
res, err := client.Call(ctx, req)
Defensive patterns

Strategy: try-catch

Validate before calling

func hasAuthHeader(md metadata.Metadata) bool {
	_, ok := md.Get("Authorization")
	if !ok {
		_, ok = md.Get("authorization")
	}
	return ok
}
// if !hasAuthHeader(md) { md = auth.TokenToMetadata(md, token) }

Type guard

func isMissingToken(err error) bool { return errors.Is(err, auth.ErrMissingToken) }

Try / catch

token, err := auth.TokenFromMetadata(md)
if errors.Is(err, auth.ErrMissingToken) {
	return errors.New("unauthorized: no bearer token supplied") // 401 response
}

Prevention

When it happens

Trigger: Calling TokenFromMetadata(md) where md lacks the Authorization key; a client wrapper (auth wrapper) not configured to inject the token; an inbound request that dropped metadata during proxying or broker hops.

Common situations: Client built without the auth wrapper so the Bearer header is never set; gateway stripping Authorization before forwarding; metadata key spelled differently (e.g. custom casing not covered by the two lookups); unauthenticated probes hitting protected endpoints.

Related errors


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