{"record":{"id":"64309114b64b10a2","repo":"Tencent/WeKnora","slug":"oidc-provider-returned-no-user-claims","errorCode":null,"errorMessage":"OIDC provider returned no user claims","messagePattern":"OIDC provider returned no user claims","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/user.go","lineNumber":1615,"sourceCode":"\t\t}\n\t}\n\n\tif strings.TrimSpace(cfg.UserInfoEndpoint) != \"\" && strings.TrimSpace(tokenResp.AccessToken) != \"\" {\n\t\tuserInfoClaims, err := s.fetchOIDCUserInfo(ctx, cfg.UserInfoEndpoint, tokenResp.AccessToken)\n\t\tif err != nil {\n\t\t\tif !verifiedFromIDToken {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to fetch OIDC userinfo: %w\", err)\n\t\t\t}\n\t\t\tlogger.Warnf(ctx, \"Failed to fetch OIDC userinfo, using verified id_token claims: %v\", err)\n\t\t} else {\n\t\t\tfor k, v := range userInfoClaims {\n\t\t\t\tclaims[k] = v\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(claims) == 0 {\n\t\treturn nil, errors.New(\"OIDC provider returned no user claims\")\n\t}\n\n\tinfo := &types.OIDCUserInfo{Claims: claims}\n\tif sub, _ := claims[\"sub\"].(string); sub != \"\" {\n\t\tinfo.Subject = sub\n\t}\n\tinfo.Username = extractClaimAsString(claims, cfg.UserInfoMapping.Username)\n\tinfo.Email = extractClaimAsString(claims, cfg.UserInfoMapping.Email)\n\tif info.Username == \"\" {\n\t\tinfo.Username = extractClaimAsString(claims, \"preferred_username\")\n\t}\n\tif info.Username == \"\" {\n\t\tinfo.Username = extractClaimAsString(claims, \"name\")\n\t}\n\tif info.Username == \"\" && info.Email != \"\" {\n\t\tinfo.Username = strings.Split(info.Email, \"@\")[0]\n\t}\n\treturn info, nil","sourceCodeStart":1597,"sourceCodeEnd":1633,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/user.go#L1597-L1633","documentation":"resolveOIDCUserInfo merges claims from the OIDC ID token and/or the userinfo endpoint. If the resulting claims map is completely empty, the provider returned nothing usable, so the service refuses to construct an OIDCUserInfo rather than fabricating an identity. This guards against misconfigured or broken providers yielding unauthenticated-but-successful logins.","triggerScenarios":"LoginWithOIDC calls resolveOIDCUserInfo; both the verified id_token claims and the userinfo endpoint response decode to empty maps (e.g. token has no claims and userinfo returned {}), so len(claims)==0.","commonSituations":"Provider returns a userinfo response with no body or '{}'; a test/broken provider issues a minimal id_token with no claims; middleware upstream strips the userinfo JSON body; misconfigured userinfo endpoint pointing at an empty page.","solutions":["Check the provider's userinfo endpoint and id_token actually contain claims (test with curl or jwt.io).","Verify the OIDC discovery/userinfo URL is correct and returns application/json.","Ensure required scopes (openid, profile, email) are requested so claims are populated.","Inspect proxy/gateway middleware that may drop or truncate response bodies."],"exampleFix":"// before: provider userinfo returns {}\nGET /userinfo -> {}\n// after: request proper scopes so claims are issued\nauthURL.Query().Set(\"scope\", \"openid profile email\")","handlingStrategy":"validation","validationCode":"if info == nil || len(info.Claims) == 0 {\n    return fmt.Errorf(\"oidc login failed: provider returned no user claims\")\n}","typeGuard":"func hasOIDCClaims(info *types.OIDCUserInfo) bool {\n    return info != nil && len(info.Claims) > 0 && info.Subject != \"\"\n}","tryCatchPattern":null,"preventionTips":["Always request the openid scope (plus profile/email as needed).","Log (redacted) userinfo response length in development to detect empty bodies early.","Test the provider's userinfo endpoint directly with curl before integrating."],"tags":["oidc","authentication","empty-claims"],"backgroundTag":"oidc-empty-userinfo-claims","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}