semaphoreui/semaphore · error

OIDC sign-in failed: could not read user info from the…

Error message

OIDC sign-in failed: could not read user info from the provider. Contact your administrator.

What it means

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.'

Solutions

  1. Inspect the server log line emitted just before this response for the real error
  2. Verify the provider config's scopes include openid (plus email/profile as needed) and client_id matches the token audience
  3. Restart/retry to re-fetch the IdP's JWKS if signing keys were rotated
  4. Check IdP health/status page for outages
  5. Confirm claim-mapping settings in the provider config match what the IdP actually emits

Example fix

// before
scopes: ["openid"]
// after - request claims the mapping expects
scopes: ["openid", "email", "profile"]
Defensive patterns

Strategy: retry

Validate before calling

rawIDToken, _ := oauth2Token.Extra("id_token").(string)
if rawIDToken == "" {
    // ensure userinfo endpoint is configured and reachable
    if err := checkDiscoveryURL(issuer); err != nil { return err }
}

Try / catch

claims, err := claimOidcToken(idToken, provider)
if err != nil {
    // one retry after JWKS refresh, then surface 502
    time.Sleep(500 * time.Millisecond)
    claims, err = claimOidcToken(verifier.Verify(ctx, rawIDToken), provider)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07). Data as JSON: /api/errors/836008728e3780a6. Report an issue: GitHub.

Appendix: source

Thrown at api/login.go:945

			if userInfo.Email == "" {
				claims, err = claimOidcUserInfo(userInfo, provider)
			} else {
				claims.email = userInfo.Email
				claims.name = userInfo.Profile
				claims.sub = userInfo.Subject
				claims.emailVerified = oidcEmailVerified(userInfo, provider)
			}
		}

		claims.username = getRandomUsername()
		if userInfo.Profile == "" {
			claims.name = getRandomProfileName()
		}
	}

	if err != nil {
		log.Error(err.Error())
		http.Error(w, "OIDC sign-in failed: could not read user info from the provider. Contact your administrator.", http.StatusBadGateway)
		return
	}

	if claims.sub == "" {
		log.Error(fmt.Errorf("oidc provider %s returned no sub claim", pid))
		http.Error(w, "OIDC sign-in failed: the provider returned no user ID (sub claim). Contact your administrator.", http.StatusBadGateway)
		return
	}

	if stateData.Link {
		session, ok := getSession(r)
		if !ok || !session.IsVerified() {
			http.Error(w, "You must be signed in to link an external account.", http.StatusUnauthorized)
			return
		}

		sessionUser, uErr := helpers.Store(r).GetUser(session.UserID)
		if uErr != nil {

View on GitHub (pinned to 1774ccb71a)