{"record":{"id":"836008728e3780a6","repo":"semaphoreui/semaphore","slug":"oidc-sign-in-failed-could-not-read-user-info-from","errorCode":null,"errorMessage":"OIDC sign-in failed: could not read user info from the provider. Contact your administrator.","messagePattern":"OIDC sign-in failed: could not read user info from the provider\\. Contact your administrator\\.","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"api/login.go","lineNumber":945,"sourceCode":"\t\t\tif userInfo.Email == \"\" {\n\t\t\t\tclaims, err = claimOidcUserInfo(userInfo, provider)\n\t\t\t} else {\n\t\t\t\tclaims.email = userInfo.Email\n\t\t\t\tclaims.name = userInfo.Profile\n\t\t\t\tclaims.sub = userInfo.Subject\n\t\t\t\tclaims.emailVerified = oidcEmailVerified(userInfo, provider)\n\t\t\t}\n\t\t}\n\n\t\tclaims.username = getRandomUsername()\n\t\tif userInfo.Profile == \"\" {\n\t\t\tclaims.name = getRandomProfileName()\n\t\t}\n\t}\n\n\tif err != nil {\n\t\tlog.Error(err.Error())\n\t\thttp.Error(w, \"OIDC sign-in failed: could not read user info from the provider. Contact your administrator.\", http.StatusBadGateway)\n\t\treturn\n\t}\n\n\tif claims.sub == \"\" {\n\t\tlog.Error(fmt.Errorf(\"oidc provider %s returned no sub claim\", pid))\n\t\thttp.Error(w, \"OIDC sign-in failed: the provider returned no user ID (sub claim). Contact your administrator.\", http.StatusBadGateway)\n\t\treturn\n\t}\n\n\tif stateData.Link {\n\t\tsession, ok := getSession(r)\n\t\tif !ok || !session.IsVerified() {\n\t\t\thttp.Error(w, \"You must be signed in to link an external account.\", http.StatusUnauthorized)\n\t\t\treturn\n\t\t}\n\n\t\tsessionUser, uErr := helpers.Store(r).GetUser(session.UserID)\n\t\tif uErr != nil {","sourceCodeStart":927,"sourceCodeEnd":963,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/api/login.go#L927-L963","documentation":"After exchanging the code, oidcRedirect extracts claims either from the verified ID token (claimOidcToken) or from the UserInfo endpoint. Any error in that chain (verification failure, UserInfo HTTP failure, claim mapping error) is collapsed into HTTP 502 'could not read user info from the provider.'","triggerScenarios":"ID token verification fails (wrong client_id audience, expired token, unknown signing key), UserInfo endpoint returns an error, provider omits expected claims that claimOidcToken/claimOidcUserInfo require, or no id_token is present and the UserInfo call fails.","commonSituations":"IdP issued token with unexpected audience; IdP rotation of signing keys not yet fetched; provider's scopes changed so email/profile claims disappeared; upstream IdP outage (502/503) on the userinfo endpoint.","solutions":["Inspect the server log line emitted just before this response for the real error","Verify the provider config's scopes include openid (plus email/profile as needed) and client_id matches the token audience","Restart/retry to re-fetch the IdP's JWKS if signing keys were rotated","Check IdP health/status page for outages","Confirm claim-mapping settings in the provider config match what the IdP actually emits"],"exampleFix":"// before\nscopes: [\"openid\"]\n// after - request claims the mapping expects\nscopes: [\"openid\", \"email\", \"profile\"]","handlingStrategy":"retry","validationCode":"rawIDToken, _ := oauth2Token.Extra(\"id_token\").(string)\nif rawIDToken == \"\" {\n    // ensure userinfo endpoint is configured and reachable\n    if err := checkDiscoveryURL(issuer); err != nil { return err }\n}","typeGuard":null,"tryCatchPattern":"claims, err := claimOidcToken(idToken, provider)\nif err != nil {\n    // one retry after JWKS refresh, then surface 502\n    time.Sleep(500 * time.Millisecond)\n    claims, err = claimOidcToken(verifier.Verify(ctx, rawIDToken), provider)\n}","preventionTips":["Request openid, email, profile scopes explicitly","Map provider claim names in config to match actual IdP token contents","Watch for IdP key rotation; refresh JWKS periodically","Alert on IdP userinfo endpoint health"],"tags":["oidc","http-502","userinfo"],"backgroundTag":"upstream-api-error","analyzedSha":"1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa","analyzedAt":"2026-09-07T11:00:33.293Z","contentChangedAt":"2026-09-07T11:00:33.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}