oauth2-proxy/oauth2-proxy · error
unable to extract username from userinfo endpoint: %v
Error message
unable to extract username from userinfo endpoint: %v
What it means
Same EnrichSession flow in providers/srht.go: after successfully extracting email, the provider reads data.me.username; if that path is missing or not a string, it returns "unable to extract username from userinfo endpoint: %v". It populates session.PreferredUsername and session.User, so failure here leaves the session without a username.
Source
Thrown at providers/srht.go:98
SetHeader("Content-Type", "application/json").
SetHeader("Authorization", "Bearer "+s.AccessToken).
WithBody(bytes.NewBufferString(`{"query": "{ me { username, email } }"}`)).
Do().
UnmarshalSimpleJSON()
if err != nil {
logger.Errorf("failed making request %v", err)
return err
}
email, err := json.GetPath("data", "me", "email").String()
if err != nil {
return fmt.Errorf("unable to extract email from userinfo endpoint: %v", err)
}
s.Email = email
username, err := json.GetPath("data", "me", "username").String()
if err != nil {
return fmt.Errorf("unable to extract username from userinfo endpoint: %v", err)
}
s.PreferredUsername = username
s.User = username
return nil
}
// ValidateSession validates the AccessToken
func (p *SourceHutProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool {
return validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken))
}
View on GitHub (pinned to 33c2eb92de)
Solutions
- Inspect the wrapped %v message and the raw response body; a GraphQL 'errors' array with 200 status is the usual culprit.
- Re-authenticate: an expired/revoked access token can yield error-shaped responses; ensure token refresh happens before EnrichSession.
- Verify requested scopes include the fields needed for username and that the configured srht API base URL matches your instance.
- Add a check for a GraphQL errors key in the response before path extraction and surface the upstream error message.
Example fix
// before
username, err := json.GetPath("data", "me", "username").String()
// after
if errs := json.Get("errors"); errs != nil {
return fmt.Errorf("sourcehut API returned errors: %v", errs)
}
username, err := json.GetPath("data", "me", "username").String() Defensive patterns
Strategy: try-catch
Validate before calling
var probe map[string]any
json.NewDecoder(resp.Body).Decode(&probe)
if e, ok := probe["errors"]; ok { /* GraphQL error payload despite HTTP 200 */ _ = e }
if m, ok := probe["data"].(map[string]any); ok {
if me, ok := m["me"].(map[string]any); ok {
if _, ok := me["username"].(string); !ok { /* username missing */ }
}
} Type guard
func hasUsername(body map[string]any) bool {
d, ok := body["data"].(map[string]any)
if !ok { return false }
me, ok := d["me"].(map[string]any)
if !ok { return false }
u, ok := me["username"].(string)
return ok && u != ""
} Try / catch
if err := p.EnrichSession(ctx, s, tok); err != nil {
if strings.Contains(err.Error(), "unable to extract username") {
// token likely expired/revoked or scope missing; trigger re-auth and log body
return fmt.Errorf("sourcehut username unavailable (re-auth suggested): %w", err)
}
return err
} Prevention
- Detect GraphQL 'errors' arrays in 200 responses before path extraction.
- Ensure token refresh runs so EnrichSession never uses an expired access token.
- Confirm the requested scopes cover account username fields on your SourceHut instance.
- Log the full userinfo body on enrichment failure to distinguish schema vs auth problems.
When it happens
Trigger: EnrichSession on the Sourcehut provider gets a 200 JSON response where data.me.username is absent, null, or non-string — e.g. truncated response, error object under 'errors' instead of 'data', or a proxy stripping fields.
Common situations: Token scope too narrow for account metadata; SourceHut GraphQL returning {"errors":[...]} due to an expired/revoked token while HTTP status stays 200; network middleboxes (corporate proxy) mangling the body; wrong instance URL (sr.ht vs custom SourceHut deployment) with different schema.
Related errors
- unable to extract email from userinfo endpoint: %v
- error making request to profile URL: %v
- missing email
- email %s not listed as verified
- unable to extract id from userinfo endpoint: %v
AI-assisted analysis of oauth2-proxy/oauth2-proxy@33c2eb92de (2026-09-06).
Data as JSON: /api/errors/359351f49f89cf09.
Report an issue: GitHub.