{"record":{"id":"0cb7f58b704143e0","repo":"weaviate/weaviate","slug":"cannot-delete-root-user","errorCode":null,"errorMessage":"cannot delete root user","messagePattern":"cannot delete root user","errorType":"http","errorClass":null,"httpStatus":422,"severity":"error","filePath":"adapters/handlers/rest/db_users/handlers_db_users.go","lineNumber":554,"sourceCode":"\nfunc (h *dynUserHandler) deleteUser(params users.DeleteUserParams, principal *models.Principal) middleware.Responder {\n\tctx := params.HTTPRequest.Context()\n\tinternalKey := namespacing.QualifyUserIDForLookup(principal, h.namespacesEnabled, params.UserID)\n\n\tif err := h.authorizer.Authorize(ctx, principal, authorization.DELETE, authorization.Users(internalKey)...); err != nil {\n\t\treturn users.NewDeleteUserForbidden().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))\n\t}\n\n\tif !h.dbUserEnabled {\n\t\treturn users.NewDeleteUserUnprocessableEntity().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, errors.New(\"db user management is not enabled\")))\n\t}\n\n\tif internalKey == principal.Username {\n\t\treturn users.NewDeleteUserUnprocessableEntity().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf(\"cannot delete its own user %q\", params.UserID)))\n\t}\n\n\tif h.isRootUser(internalKey) {\n\t\treturn users.NewDeleteUserUnprocessableEntity().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, errors.New(\"cannot delete root user\")))\n\t}\n\texistingUsers, err := h.dbUsers.GetUsers(internalKey)\n\tif err != nil {\n\t\treturn users.NewDeleteUserInternalServerError().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))\n\t}\n\tif len(existingUsers) == 0 {\n\t\tif h.staticUserExists(internalKey) {\n\t\t\treturn users.NewDeleteUserUnprocessableEntity().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf(\"user '%v' is static user\", params.UserID)))\n\t\t}\n\t\treturn users.NewDeleteUserNotFound()\n\t}\n\troles, err := h.dbUsers.GetRolesForUserOrGroup(internalKey, authentication.AuthTypeDb, false)\n\tif err != nil {\n\t\treturn users.NewDeleteUserInternalServerError().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))\n\t}\n\tif len(roles) > 0 {\n\t\troleNames := make([]string, 0, len(roles))\n\t\tfor name := range roles {","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/adapters/handlers/rest/db_users/handlers_db_users.go#L536-L572","documentation":"The built-in root user cannot be removed: deleteUser explicitly rejects any delete request whose target userId matches the root user name and returns HTTP 422 with this message. The root user is the bootstrap admin principal and is required for administering the cluster, so deleting it would lock out management.","triggerScenarios":"Calling DELETE /v1/users/db/{userId} where userId resolves to the configured root user name (e.g. 'root').","commonSituations":"Bulk user-deletion scripts iterating all user names including root; janitor jobs syncing the user list with an external IdP that does not know about the reserved root account.","solutions":["Exclude the root user name from delete automation (skip-list it before calling DELETE).","Fetch the configured root user name from cluster configuration and guard the delete loop against it.","If root should effectively be disabled, restrict its permissions via authorization config rather than deleting it."],"exampleFix":"// before\nfor _, u := range users { client.Users.DbDelete(users.NewDbDeleteParams().WithUserID(u)) }\n\n// after\nfor _, u := range users {\n  if u == \"root\" { continue }\n  client.Users.DbDelete(users.NewDbDeleteParams().WithUserID(u))\n}","handlingStrategy":"validation","validationCode":"const rootUser = \"root\" // match configured root name\nif target == rootUser { return errors.New(\"root user cannot be deleted\") }","typeGuard":"func isRootUser(name, rootUserName string) bool { return name == rootUserName }","tryCatchPattern":"var uerr *users.DeleteUserUnprocessableEntity\nif err := deleteUser(u); errors.As(err, &uerr) {\n  if strings.Contains(uerr.Payload.Error[0].Message, \"root user\") { log.Warnf(\"skipped root user %s\", u) }\n}","preventionTips":["Always skip-list the root account in bulk delete loops","Derive the reserved name from configuration, not hardcoded assumptions","Audit external IdP sync jobs so they never treat built-in accounts as deletable"],"tags":["rest-api","db-users","root-user","protection"],"backgroundTag":"protected-resource-deletion","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}