{"record":{"id":"b028f98b44299760","repo":"ory/hydra","slug":"session-must-be-of-type-jwtsessioncontainer-but-go","errorCode":null,"errorMessage":"Session must be of type JWTSessionContainer but got type: %T","messagePattern":"Session must be of type JWTSessionContainer but got type: %T","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fosite/handler/oauth2/strategy_jwt.go","lineNumber":90,"sourceCode":"\tcase v.Has(jwt.ValidationErrorUnverifiable | jwt.ValidationErrorSignatureInvalid):\n\t\treturn fosite.ErrTokenSignatureMismatch\n\tcase v.Has(jwt.ValidationErrorExpired):\n\t\treturn fosite.ErrTokenExpired\n\tcase v.Has(jwt.ValidationErrorAudience |\n\t\tjwt.ValidationErrorIssuedAt |\n\t\tjwt.ValidationErrorIssuer |\n\t\tjwt.ValidationErrorNotValidYet |\n\t\tjwt.ValidationErrorId |\n\t\tjwt.ValidationErrorClaimsInvalid):\n\t\treturn fosite.ErrTokenClaim\n\tdefault:\n\t\treturn fosite.ErrRequestUnauthorized\n\t}\n}\n\nfunc (h *DefaultJWTStrategy) generate(ctx context.Context, tokenType fosite.TokenType, requester fosite.Requester) (string, string, error) {\n\tif jwtSession, ok := requester.GetSession().(JWTSessionContainer); !ok {\n\t\treturn \"\", \"\", errors.Errorf(\"Session must be of type JWTSessionContainer but got type: %T\", requester.GetSession())\n\t} else if claims := jwtSession.GetJWTClaims(); claims == nil {\n\t\treturn \"\", \"\", errors.New(\"GetTokenClaims() must not be nil\")\n\t} else {\n\t\tclaims.\n\t\t\tWith(\n\t\t\t\tjwtSession.GetExpiresAt(tokenType),\n\t\t\t\trequester.GetGrantedScopes(),\n\t\t\t\trequester.GetGrantedAudience(),\n\t\t\t).\n\t\t\tWithDefaults(\n\t\t\t\ttime.Now().UTC(),\n\t\t\t\th.Config.GetAccessTokenIssuer(ctx),\n\t\t\t).\n\t\t\tWithScopeField(\n\t\t\t\th.Config.GetJWTScopeField(ctx),\n\t\t\t)\n\n\t\treturn h.Signer.Generate(ctx, claims.ToMapClaims(), jwtSession.GetJWTHeader())","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/fosite/handler/oauth2/strategy_jwt.go#L72-L108","documentation":"fosite's DefaultJWTStrategy.generate requires the requester's session to implement JWTSessionContainer; any other Session implementation cannot contribute JWT claims and is rejected with this type assertion error. It is a programming/configuration error: the session type attached to the request is wrong for JWT token generation.","triggerScenarios":"Calling GenerateAccessToken (or any generate-path) on a strategy built with DefaultJWTStrategy while the request's GetSession() returns a plain/default session (e.g. fosite's DefaultSession or a custom session not implementing JWTSessionContainer) instead of a JWT-capable session (e.g. handler/oauth2.JWTSession or an HMACSession wrapper implementing GetJWTClaims).","commonSituations":"Switching the access token strategy to jwt in config without changing the session store/manager to create JWTSessionContainer sessions; custom Session types used with the default strategy; upgrading fosite where session wiring was changed.","solutions":["Use/attach a session type implementing JWTSessionContainer (e.g. compose fosite's JWTSession or implement GetJWTClaims/GetExpiresAt/GetSubject) for JWT strategy requests","Ensure the session manager/storage creates the JWT-capable session type for token requests, not the default session","If you need opaque tokens, configure the hmac strategy instead of jwt for that grant type","Add a startup type check: if _, ok := sess.(fositeJWT.JWTSessionContainer); !ok { fail fast }"],"exampleFix":"// before\nsession := &fosite.DefaultSession{Subject: user.ID}\n// after\nsession := &oauth2.JWTSession{Session: &fosite.DefaultSession{Subject: user.ID}, Header: &jwt.Header{Extra: map[string]interface{}{\"alg\":\"RS256\"}}}","handlingStrategy":"type-guard","validationCode":"if _, ok := req.GetSession().(JWTSessionContainer); !ok {\n    return fmt.Errorf(\"token endpoint misconfigured: session %T does not implement JWTSessionContainer\", req.GetSession())\n}","typeGuard":"func asJWTSession(s fosite.Session) (JWTSessionContainer, bool) {\n    js, ok := s.(JWTSessionContainer)\n    return js, ok\n}","tryCatchPattern":"resp, err := oauth2Client.GetAccessToken(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"must be of type JWTSessionContainer\") {\n    log.Fatalf(\"config error: jwt strategy requires JWTSessionContainer sessions: %v\", err)\n}","preventionTips":["Pair the jwt access token strategy with a session type that embeds JWTSessionContainer (e.g. oauth2.JWTSession)","Keep one session factory used by all token handlers so the session type can't drift","Add an integration test that performs a token request with the jwt strategy enabled","Check fosite docs when switching strategies — session types differ between hmac and jwt"],"tags":["oauth2","fosite","jwt","type-assertion","session"],"backgroundTag":"jwt-session-type-mismatch","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}