AlistGo/alist · error

cannot get username from SSO provider

Error message

cannot get username from SSO provider

What it means

Returned by autoRegister in ssologin.go when SSO auto-registration is enabled, the user lookup returned gorm.ErrRecordNotFound, but the username claim extracted from the provider's userinfo response is empty. The username becomes the local account's identity (and its generated random password is unrecoverable), so registration cannot proceed without it.

Source

Thrown at server/handles/ssologin.go:150

	return &oauth2.Config{
		ClientID:     clientId,
		ClientSecret: clientSecret,
		RedirectURL:  redirectUri,

		// Discovery returns the OAuth2 endpoints.
		Endpoint: provider.Endpoint(),

		// "openid" is a required scope for OpenID Connect flows.
		Scopes: append([]string{oidc.ScopeOpenID, "profile"}, extraScopes...),
	}, nil
}

func autoRegister(username, userID string, err error) (*model.User, error) {
	if !errors.Is(err, gorm.ErrRecordNotFound) || !setting.GetBool(conf.SSOAutoRegister) {
		return nil, err
	}
	if username == "" {
		return nil, errors.New("cannot get username from SSO provider")
	}
	user := &model.User{
		ID:         0,
		Username:   username,
		Password:   random.String(16),
		Permission: int32(setting.GetInt(conf.SSODefaultPermission, 0)),
		BasePath:   setting.GetStr(conf.SSODefaultDir),
		Role:       model.Roles{op.GetDefaultRoleID()},
		Disabled:   false,
		SsoID:      userID,
	}
	if err = db.CreateUser(user); err != nil {
		if strings.HasPrefix(err.Error(), "UNIQUE constraint failed") && strings.HasSuffix(err.Error(), "username") {
			user.Username = user.Username + "_" + userID
			if err = db.CreateUser(user); err != nil {
				return nil, err
			}
		} else {

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Check which JSON field the provider actually returns for the username and set the matching username field in the SSO platform settings
  2. Request the profile (and appropriate extra) scopes in the SSO configuration
  3. Test the provider's userinfo endpoint directly with a real token and inspect the payload keys
  4. As a workaround, create the local user manually and link it via SSO ID, or disable auto-register

Example fix

// before: provider returns {"login": ...} but setting says usernameField="name"
// after: set the SSO platform's username field to the key that is non-empty (e.g. "login")
Defensive patterns

Strategy: validation

Validate before calling

// Fetch userinfo with a test token and confirm the username field is non-empty
username := utils.Json.Get(userinfoBody, cfg.UsernameField).ToString()
if username == "" {
    return fmt.Errorf("SSO provider does not return field %q", cfg.UsernameField)
}

Try / catch

user, err := autoRegister(username, userID, err)
if err != nil && strings.Contains(err.Error(), "cannot get username from SSO provider") {
    // provider payload lacks the configured username claim — fix field mapping or scopes
}

Prevention

When it happens

Trigger: First login via an SSO/OIDC provider whose userinfo response lacks the configured username field (e.g. platform-specific usernameField not returned, 'profile' scope not granted, or the field maps to an empty claim).

Common situations: OIDC providers that only return the claim when the 'profile' scope is requested; custom OAuth platforms where the username field name in settings ('login', 'name', 'username') does not match the JSON key actually returned; private GitHub installations or GitLab with restricted profile visibility.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/a269d252735d1ead. Report an issue: GitHub.