{"record":{"id":"b0c39c02c134c2e1","repo":"go-kit/kit","slug":"token-up-for-parsing-was-not-passed-through-the-co","errorCode":null,"errorMessage":"token up for parsing was not passed through the context","messagePattern":"token up for parsing was not passed through the context","errorType":"exception","errorClass":"ErrTokenContextMissing","httpStatus":401,"severity":"error","filePath":"auth/jwt/middleware.go","lineNumber":30,"sourceCode":"\nconst (\n\t// JWTContextKey holds the key used to store a JWT in the context.\n\tJWTContextKey contextKey = \"JWTToken\"\n\n\t// JWTTokenContextKey is an alias for JWTContextKey.\n\t//\n\t// Deprecated: prefer JWTContextKey.\n\tJWTTokenContextKey = JWTContextKey\n\n\t// JWTClaimsContextKey holds the key used to store the JWT Claims in the\n\t// context.\n\tJWTClaimsContextKey contextKey = \"JWTClaims\"\n)\n\nvar (\n\t// ErrTokenContextMissing denotes a token was not passed into the parsing\n\t// middleware's context.\n\tErrTokenContextMissing = errors.New(\"token up for parsing was not passed through the context\")\n\n\t// ErrTokenInvalid denotes a token was not able to be validated.\n\tErrTokenInvalid = errors.New(\"JWT was invalid\")\n\n\t// ErrTokenExpired denotes a token's expire header (exp) has since passed.\n\tErrTokenExpired = errors.New(\"JWT is expired\")\n\n\t// ErrTokenMalformed denotes a token was not formatted as a JWT.\n\tErrTokenMalformed = errors.New(\"JWT is malformed\")\n\n\t// ErrTokenNotActive denotes a token's not before header (nbf) is in the\n\t// future.\n\tErrTokenNotActive = errors.New(\"token is not valid yet\")\n\n\t// ErrUnexpectedSigningMethod denotes a token was signed with an unexpected\n\t// signing method.\n\tErrUnexpectedSigningMethod = errors.New(\"unexpected signing method\")\n)","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/go-kit/kit/blob/78fbbceece7bbcf073bee814a7772f4397ea756c/auth/jwt/middleware.go#L12-L48","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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)","On the client, wrap the endpoint with jwt.NewSigner(kid, key, method, claims) before the HTTP transport so the token lands in context","In unit tests, build the context manually: ctx = context.WithValue(ctx, jwt.JWTContextKey, \"<token>\") before invoking the endpoint","Verify the stored value is a plain string token, not the full header or a struct"],"exampleFix":"// before: server parses JWTs but nothing puts the token in context\nhandler := httptransport.NewServer(makeEndpoint(jwt.NewParser(kf, jwt.SigningMethodHS256, jwt.MapClaimsFactory)), decode, encode)\n// -> \"token up for parsing was not passed through the context\"\n\n// after: extract the Bearer token before the endpoint runs\nstrt := func(ctx context.Context, r *http.Request) context.Context {\n\ttoken := strings.TrimPrefix(r.Header.Get(\"Authorization\"), \"Bearer \")\n\treturn context.WithValue(ctx, jwt.JWTContextKey, token)\n}\nhandler := httptransport.NewServer(jwt.NewParser(kf, jwt.SigningMethodHS256, jwt.MapClaimsFactory)(makeEndpoint), decode, encode, httptransport.ServerBefore(strt))","handlingStrategy":"validation","validationCode":"func tokenInContext(ctx context.Context) bool {\n\t_, ok := ctx.Value(jwt.JWTContextKey).(string)\n\treturn ok && ctx.Value(jwt.JWTContextKey).(string) != \"\"\n}\n// guard inside your transport RequestFunc or before invoking the endpoint","typeGuard":"func ctxToken(ctx context.Context) (string, bool) {\n\tt, ok := ctx.Value(jwt.JWTContextKey).(string)\n\treturn t, ok && t != \"\"\n}","tryCatchPattern":"if _, err := ep(ctx, req); err != nil {\n\tif errors.Is(err, jwt.ErrTokenContextMissing) {\n\t\t// 401 with WWW-Authenticate: Bearer — the client sent no extractable token\n\t}\n}","preventionTips":["Centralize the ServerBefore RequestFunc that extracts the Authorization header; never mount a JWT-parsing server without it","On the client, always compose jwt.NewSigner before the HTTP transport so tests and prod share the same chain","In unit tests, seed the context via context.WithValue(ctx, jwt.JWTContextKey, testToken) through one helper"],"tags":["go","go-kit","jwt","authentication","context","http-headers"],"backgroundTag":null,"analyzedSha":"78fbbceece7bbcf073bee814a7772f4397ea756c","analyzedAt":"2026-08-15T22:31:35.570Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}