{"record":{"id":"a269d252735d1ead","repo":"AlistGo/alist","slug":"cannot-get-username-from-sso-provider","errorCode":null,"errorMessage":"cannot get username from SSO provider","messagePattern":"cannot get username from SSO provider","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"server/handles/ssologin.go","lineNumber":150,"sourceCode":"\treturn &oauth2.Config{\n\t\tClientID:     clientId,\n\t\tClientSecret: clientSecret,\n\t\tRedirectURL:  redirectUri,\n\n\t\t// Discovery returns the OAuth2 endpoints.\n\t\tEndpoint: provider.Endpoint(),\n\n\t\t// \"openid\" is a required scope for OpenID Connect flows.\n\t\tScopes: append([]string{oidc.ScopeOpenID, \"profile\"}, extraScopes...),\n\t}, nil\n}\n\nfunc autoRegister(username, userID string, err error) (*model.User, error) {\n\tif !errors.Is(err, gorm.ErrRecordNotFound) || !setting.GetBool(conf.SSOAutoRegister) {\n\t\treturn nil, err\n\t}\n\tif username == \"\" {\n\t\treturn nil, errors.New(\"cannot get username from SSO provider\")\n\t}\n\tuser := &model.User{\n\t\tID:         0,\n\t\tUsername:   username,\n\t\tPassword:   random.String(16),\n\t\tPermission: int32(setting.GetInt(conf.SSODefaultPermission, 0)),\n\t\tBasePath:   setting.GetStr(conf.SSODefaultDir),\n\t\tRole:       model.Roles{op.GetDefaultRoleID()},\n\t\tDisabled:   false,\n\t\tSsoID:      userID,\n\t}\n\tif err = db.CreateUser(user); err != nil {\n\t\tif strings.HasPrefix(err.Error(), \"UNIQUE constraint failed\") && strings.HasSuffix(err.Error(), \"username\") {\n\t\t\tuser.Username = user.Username + \"_\" + userID\n\t\t\tif err = db.CreateUser(user); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t} else {","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/server/handles/ssologin.go#L132-L168","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Check which JSON field the provider actually returns for the username and set the matching username field in the SSO platform settings","Request the profile (and appropriate extra) scopes in the SSO configuration","Test the provider's userinfo endpoint directly with a real token and inspect the payload keys","As a workaround, create the local user manually and link it via SSO ID, or disable auto-register"],"exampleFix":"// before: provider returns {\"login\": ...} but setting says usernameField=\"name\"\n// after: set the SSO platform's username field to the key that is non-empty (e.g. \"login\")","handlingStrategy":"validation","validationCode":"// Fetch userinfo with a test token and confirm the username field is non-empty\nusername := utils.Json.Get(userinfoBody, cfg.UsernameField).ToString()\nif username == \"\" {\n    return fmt.Errorf(\"SSO provider does not return field %q\", cfg.UsernameField)\n}","typeGuard":null,"tryCatchPattern":"user, err := autoRegister(username, userID, err)\nif err != nil && strings.Contains(err.Error(), \"cannot get username from SSO provider\") {\n    // provider payload lacks the configured username claim — fix field mapping or scopes\n}","preventionTips":["Request the profile scope plus any extra scopes carrying the username claim","Inspect the provider's userinfo JSON once with a manual token and pin the field name in settings","Have a fallback: pre-create local users linked by SSO ID instead of relying on auto-register"],"tags":["sso","oauth","oidc","auth","auto-registration"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}