{"record":{"id":"1322537e4629468c","repo":"gotify/server","slug":"failed-to-create-user-w","errorCode":null,"errorMessage":"failed to create user: %w","messagePattern":"failed to create user: %w","errorType":"http","errorClass":null,"httpStatus":500,"severity":"critical","filePath":"api/oidc.go","lineNumber":519,"sourceCode":"\treturn user, 0, nil\n}\n\nfunc (a *OIDCAPI) registerUser(username, oidcID string, hasAdminGroup bool) (*model.User, int, error) {\n\tif !a.AutoRegister {\n\t\treturn nil, http.StatusForbidden, errors.New(\"user does not exist and auto-registration is disabled\")\n\t}\n\tuser := &model.User{\n\t\tName:   username,\n\t\tPass:   nil,\n\t\tOIDCID: &oidcID,\n\t}\n\n\tif len(a.GroupsAdmin) > 0 {\n\t\tuser.Admin = hasAdminGroup\n\t}\n\n\tif err := a.DB.CreateUser(user); err != nil {\n\t\treturn nil, http.StatusInternalServerError, fmt.Errorf(\"failed to create user: %w\", err)\n\t}\n\tlog.Info().Str(\"oidc_id\", oidcID).Str(\"username\", user.Name).Bool(\"admin\", user.Admin).Msg(\"OIDC auto registration\")\n\tif err := a.UserChangeNotifier.fireUserAdded(user.ID); err != nil {\n\t\tlog.Error().Err(err).Uint(\"user_id\", user.ID).Msg(\"Could not notify user change\")\n\t}\n\treturn user, 0, nil\n}\n\nfunc (a *OIDCAPI) createClient(name string, userID uint) (*model.Client, error) {\n\televatedUntil := time.Now().Add(model.DefaultElevationDuration)\n\ttokenPublic, tokenPrivate := generateClientToken()\n\tclient := &model.Client{\n\t\tName:                          name,\n\t\tToken:                         tokenPublic,\n\t\tUserID:                        userID,\n\t\tElevatedUntil:                 &elevatedUntil,\n\t\tExpiresAfterInactivitySeconds: auth.CookieMaxAge,\n\t}","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/gotify/server/blob/14bfc256276775c425f988d621dccfe705de18ac/api/oidc.go#L501-L537","documentation":"registerUser wraps a failure from DB.CreateUser while auto-provisioning a new account for a first-time OIDC login as 'failed to create user: %w' with HTTP 500. The identity is valid and unmatched, but the INSERT into the user store failed, so registration is aborted.","triggerScenarios":"First-ever OIDC login for an identity: no user by OIDC ID or username exists, registerUser builds a new model.User and a.DB.CreateUser(user) errors.","commonSituations":"Username from the claim violates DB constraints (too long, invalid chars, duplicate after race); users table out of migration; DB quota/disk full; unique index race between two simultaneous first logins.","solutions":["Check the wrapped driver error (duplicate key / constraint) in logs and address the specific constraint","Run pending DB migrations for the users table","Validate/sanitize the username claim length and characters at the IdP or in config","Retry; if it was an insert race, the second login will link instead of register"],"exampleFix":"// before\nusername := fmt.Sprint(usernameRaw)\n// after\nusername := fmt.Sprint(usernameRaw)\nif len(username) > 64 { // keep within users.name column limit\n    username = username[:64]\n}","handlingStrategy":"try-catch","validationCode":"// validate username length/charset before provisioning\nif len(username) > 64 || strings.ContainsAny(username, \"\\x00\") {\n    return errors.New(\"username from IdP violates user table constraints\")\n}","typeGuard":null,"tryCatchPattern":"user, status, err := resolveUser(...)\nif err != nil && strings.Contains(err.Error(), \"failed to create user\") {\n    var pgErr *pgconn.PgError\n    if errors.As(err, &pgErr) && pgErr.Code == \"23505\" {\n        // duplicate key race: retry login; it will link instead of register\n    }\n    http.Error(w, err.Error(), status)\n    return\n}","preventionTips":["Run pending migrations before enabling auto-registration","Cap/validate the username claim at the IdP","Handle unique-key races by retrying the login","Monitor CreateUser failures and DB disk/quota"],"tags":["database","oidc","user-provisioning","http-500"],"backgroundTag":"user-creation-failed","analyzedSha":"14bfc256276775c425f988d621dccfe705de18ac","analyzedAt":"2026-09-05T12:52:36.781Z","contentChangedAt":"2026-09-05T12:52:36.781Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}