{"record":{"id":"b27a40196a2e6189","repo":"weaviate/weaviate","slug":"cannot-create-db-user-with-root-user-name","errorCode":null,"errorMessage":"cannot create db user with root user name","messagePattern":"cannot create db user with root user name","errorType":"http","errorClass":null,"httpStatus":422,"severity":"error","filePath":"adapters/handlers/rest/db_users/handlers_db_users.go","lineNumber":442,"sourceCode":"\n\t\tif err := h.dbUsers.CreateUserWithKey(ctx, params.UserID, apiKey[:3], sha256.Sum256([]byte(apiKey)), createdAt); err != nil {\n\t\t\treturn users.NewCreateUserInternalServerError().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf(\"creating user: %w\", err)))\n\t\t}\n\n\t\treturn users.NewCreateUserCreated().WithPayload(&models.UserAPIKey{Apikey: &apiKey})\n\t}\n\n\t// Skip the RAFT round-trip when the namespace is locally known not to be\n\t// active; the apply path re-validates authoritatively.\n\tif err := namespaces.RequireActive(h.namespaces, ns); err != nil {\n\t\treturn renderCreateUserNamespaceErr(principal, err)\n\t}\n\n\tif h.staticUserExists(internalKey) {\n\t\treturn users.NewCreateUserConflict().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf(\"user '%v' already exists\", params.UserID)))\n\t}\n\tif h.isRootUser(internalKey) {\n\t\treturn users.NewCreateUserUnprocessableEntity().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, errors.New(\"cannot create db user with root user name\")))\n\t}\n\tif h.isAdminlistUser(internalKey) {\n\t\treturn users.NewCreateUserUnprocessableEntity().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, errors.New(\"cannot create db user with admin list name\")))\n\t}\n\n\texistingUser, err := h.dbUsers.GetUsers(internalKey)\n\tif err != nil {\n\t\treturn users.NewCreateUserInternalServerError().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf(\"checking user existence: %w\", err)))\n\t}\n\n\tif len(existingUser) > 0 {\n\t\treturn users.NewCreateUserConflict().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf(\"user '%v' already exists\", params.UserID)))\n\t}\n\n\tapiKey, hash, userIdentifier, err := h.getApiKey()\n\tif err != nil {\n\t\treturn users.NewCreateUserInternalServerError().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))\n\t}","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/adapters/handlers/rest/db_users/handlers_db_users.go#L424-L460","documentation":"Weaviate's dynamic DB user management API rejects a POST /users/db request whose userID matches the reserved root user name. The root user is a built-in admin principal (typically 'root', defined in config AUTHENTICATION_APIKEY_USERS) and is not a dynamic DB user, so creating a second user under that name is forbidden. The handler checks reserved names before any RAFT/DB write, returning HTTP 422 (Unprocessable Entity) with this message in the error payload.","triggerScenarios":"Calling POST /v1/users/db (or the users CreateUser REST endpoint) with body {\"userId\": \"root\"} (or whatever the configured root user name is) on a cluster with dynamic user management enabled.","commonSituations":"Scripts or provisioning automation that seed users from a list containing the built-in admin/root name; config migrations where the root user was renamed in AUTHENTICATION_APIKEY_USERS but the seed script still uses 'root'; test fixtures reusing 'root' as a sample username.","solutions":["Choose a different userId that does not match the configured root user name and retry the create call.","Check the cluster config (AUTHENTICATION_APIKEY_USERS / root user settings) to see which names are reserved before provisioning users.","If you need admin capabilities for a new user, create it with an admin role assignment instead of reusing the root name."],"exampleFix":"// before\nPOST /v1/users/db\n{\"userId\": \"root\"}  // 422 cannot create db user with root user name\n\n// after\nPOST /v1/users/db\n{\"userId\": \"app-service-user\"}  // 201 created","handlingStrategy":"validation","validationCode":"const reserved = []string{\"root\"} // match configured root user name\nif slices.Contains(reserved, params.UserID) { return errors.New(\"userId is reserved (root)\") }","typeGuard":"func isReservedUser(name, rootUserName string) bool { return name == rootUserName }","tryCatchPattern":"var uerr *users.CreateUserUnprocessableEntity\nif err := createUser(userID); errors.As(err, &uerr) { log.Warnf(\"reserved name: %v\", uerr.Payload.Error[0].Message) }","preventionTips":["Keep a reserved-names list derived from cluster config and validate userIds before create calls","Never seed users with names like 'root' or 'admin' in provisioning templates","Handle 422 payloads explicitly instead of treating them as generic failures"],"tags":["rest-api","db-users","validation","weaviate"],"backgroundTag":"reserved-username-conflict","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"}