go-kit/kit · error · ErrTokenContextMissing

token up for parsing was not passed through the context

Error message

token up for parsing was not passed through the context

What it means

Returned by jwt.NewParser when the value stored in context under JWTContextKey ("JWTToken") is absent or not a string. go-kit's design splits responsibilities: the transport layer extracts the raw token (e.g. the Authorization header) into the context, and the parser middleware reads it from there. This error means the extraction step never happened before parsing.

Source

Thrown at auth/jwt/middleware.go:30

const (
	// JWTContextKey holds the key used to store a JWT in the context.
	JWTContextKey contextKey = "JWTToken"

	// JWTTokenContextKey is an alias for JWTContextKey.
	//
	// Deprecated: prefer JWTContextKey.
	JWTTokenContextKey = JWTContextKey

	// JWTClaimsContextKey holds the key used to store the JWT Claims in the
	// context.
	JWTClaimsContextKey contextKey = "JWTClaims"
)

var (
	// ErrTokenContextMissing denotes a token was not passed into the parsing
	// middleware's context.
	ErrTokenContextMissing = errors.New("token up for parsing was not passed through the context")

	// ErrTokenInvalid denotes a token was not able to be validated.
	ErrTokenInvalid = errors.New("JWT was invalid")

	// ErrTokenExpired denotes a token's expire header (exp) has since passed.
	ErrTokenExpired = errors.New("JWT is expired")

	// ErrTokenMalformed denotes a token was not formatted as a JWT.
	ErrTokenMalformed = errors.New("JWT is malformed")

	// ErrTokenNotActive denotes a token's not before header (nbf) is in the
	// future.
	ErrTokenNotActive = errors.New("token is not valid yet")

	// ErrUnexpectedSigningMethod denotes a token was signed with an unexpected
	// signing method.
	ErrUnexpectedSigningMethod = errors.New("unexpected signing method")
)

View on GitHub (pinned to 78fbbceece)

Solutions

  1. On the server, add httptransport.ServerBefore(jwtToContext) where jwtToContext does context.WithValue(ctx, jwt.JWTContextKey, tokenString) from r.Header.Get("Authorization") (strip the Bearer prefix)
  2. On the client, wrap the endpoint with jwt.NewSigner(kid, key, method, claims) before the HTTP transport so the token lands in context
  3. In unit tests, build the context manually: ctx = context.WithValue(ctx, jwt.JWTContextKey, "<token>") before invoking the endpoint
  4. Verify the stored value is a plain string token, not the full header or a struct

Example fix

// before: server parses JWTs but nothing puts the token in context
handler := httptransport.NewServer(makeEndpoint(jwt.NewParser(kf, jwt.SigningMethodHS256, jwt.MapClaimsFactory)), decode, encode)
// -> "token up for parsing was not passed through the context"

// after: extract the Bearer token before the endpoint runs
strt := func(ctx context.Context, r *http.Request) context.Context {
	token := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")
	return context.WithValue(ctx, jwt.JWTContextKey, token)
}
handler := httptransport.NewServer(jwt.NewParser(kf, jwt.SigningMethodHS256, jwt.MapClaimsFactory)(makeEndpoint), decode, encode, httptransport.ServerBefore(strt))
Defensive patterns

Strategy: validation

Validate before calling

func tokenInContext(ctx context.Context) bool {
	_, ok := ctx.Value(jwt.JWTContextKey).(string)
	return ok && ctx.Value(jwt.JWTContextKey).(string) != ""
}
// guard inside your transport RequestFunc or before invoking the endpoint

Type guard

func ctxToken(ctx context.Context) (string, bool) {
	t, ok := ctx.Value(jwt.JWTContextKey).(string)
	return t, ok && t != ""
}

Try / catch

if _, err := ep(ctx, req); err != nil {
	if errors.Is(err, jwt.ErrTokenContextMissing) {
		// 401 with WWW-Authenticate: Bearer — the client sent no extractable token
	}
}

Prevention

When it happens

Trigger: Building an httptransport.Server without a ServerBefore RequestFunc that copies the Authorization header into ctx with jwt.JWTContextKey; calling the decorated endpoint directly (tests, internal callers) without going through NewSigner or manual context setup; storing the token under the wrong key or as a non-string type so the type assertion ctx.Value(JWTContextKey).(string) fails.

Common situations: Server wired with encoders/decoders but the ServerBefore option forgotten; client transport missing jwt.NewSigner so the token never enters the context; migrating code from the deprecated JWTTokenContextKey alias and mixing key types; middleware order placing NewParser before the token-inserting RequestFunc.

Related errors


AI-assisted analysis of go-kit/kit@78fbbceece (2026-08-15). Data as JSON: /api/errors/b0c39c02c134c2e1. Report an issue: GitHub.