weaviate/weaviate · error

cannot delete root user

Error message

cannot delete root user

What it means

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.

Source

Thrown at adapters/handlers/rest/db_users/handlers_db_users.go:554

func (h *dynUserHandler) deleteUser(params users.DeleteUserParams, principal *models.Principal) middleware.Responder {
	ctx := params.HTTPRequest.Context()
	internalKey := namespacing.QualifyUserIDForLookup(principal, h.namespacesEnabled, params.UserID)

	if err := h.authorizer.Authorize(ctx, principal, authorization.DELETE, authorization.Users(internalKey)...); err != nil {
		return users.NewDeleteUserForbidden().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))
	}

	if !h.dbUserEnabled {
		return users.NewDeleteUserUnprocessableEntity().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, errors.New("db user management is not enabled")))
	}

	if internalKey == principal.Username {
		return users.NewDeleteUserUnprocessableEntity().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf("cannot delete its own user %q", params.UserID)))
	}

	if h.isRootUser(internalKey) {
		return users.NewDeleteUserUnprocessableEntity().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, errors.New("cannot delete root user")))
	}
	existingUsers, err := h.dbUsers.GetUsers(internalKey)
	if err != nil {
		return users.NewDeleteUserInternalServerError().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))
	}
	if len(existingUsers) == 0 {
		if h.staticUserExists(internalKey) {
			return users.NewDeleteUserUnprocessableEntity().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf("user '%v' is static user", params.UserID)))
		}
		return users.NewDeleteUserNotFound()
	}
	roles, err := h.dbUsers.GetRolesForUserOrGroup(internalKey, authentication.AuthTypeDb, false)
	if err != nil {
		return users.NewDeleteUserInternalServerError().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))
	}
	if len(roles) > 0 {
		roleNames := make([]string, 0, len(roles))
		for name := range roles {

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Exclude the root user name from delete automation (skip-list it before calling DELETE).
  2. Fetch the configured root user name from cluster configuration and guard the delete loop against it.
  3. If root should effectively be disabled, restrict its permissions via authorization config rather than deleting it.

Example fix

// before
for _, u := range users { client.Users.DbDelete(users.NewDbDeleteParams().WithUserID(u)) }

// after
for _, u := range users {
  if u == "root" { continue }
  client.Users.DbDelete(users.NewDbDeleteParams().WithUserID(u))
}
Defensive patterns

Strategy: validation

Validate before calling

const rootUser = "root" // match configured root name
if target == rootUser { return errors.New("root user cannot be deleted") }

Type guard

func isRootUser(name, rootUserName string) bool { return name == rootUserName }

Try / catch

var uerr *users.DeleteUserUnprocessableEntity
if err := deleteUser(u); errors.As(err, &uerr) {
  if strings.Contains(uerr.Payload.Error[0].Message, "root user") { log.Warnf("skipped root user %s", u) }
}

Prevention

When it happens

Trigger: Calling DELETE /v1/users/db/{userId} where userId resolves to the configured root user name (e.g. 'root').

Common situations: 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.

Related errors


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/0cb7f58b704143e0. Report an issue: GitHub.