netbirdio/netbird · error

self deletion is not allowed

Error message

self deletion is not allowed

What it means

Returned in AccountManager.DeleteUsers (management/server/user.go:1271): while iterating over the target user IDs, an initiator may not delete the account they authenticate as. The check compares targetUserID with initiatorUserID and joins this error into the aggregate result instead of aborting the whole batch.

Source

Thrown at management/server/user.go:1271

func (am *DefaultAccountManager) DeleteRegularUsers(ctx context.Context, accountID, initiatorUserID string, targetUserIDs []string, userInfos map[string]*types.UserInfo) error {
	allowed, ctx, err := am.permissionsManager.ValidateUserPermissions(ctx, accountID, initiatorUserID, modules.Users, operations.Delete)
	if err != nil {
		return status.NewPermissionValidationError(err)
	}
	if !allowed {
		return status.NewPermissionDeniedError()
	}

	initiatorUser, err := am.Store.GetUserByUserID(ctx, store.LockingStrengthNone, initiatorUserID)
	if err != nil {
		return err
	}

	var allErrors error

	for _, targetUserID := range targetUserIDs {
		if initiatorUserID == targetUserID {
			allErrors = errors.Join(allErrors, errors.New("self deletion is not allowed"))
			continue
		}

		targetUser, err := am.Store.GetUserByUserID(ctx, store.LockingStrengthNone, targetUserID)
		if err != nil {
			allErrors = errors.Join(allErrors, err)
			continue
		}

		if targetUser.Role == types.UserRoleOwner {
			allErrors = errors.Join(allErrors, fmt.Errorf("unable to delete a user: %s with owner role", targetUserID))
			continue
		}

		// disable deleting integration user if the initiator is not admin service user
		if targetUser.Issued == types.UserIssuedIntegration && !initiatorUser.IsServiceUser {
			allErrors = errors.Join(allErrors, errors.New("only integration service user can delete this user"))
			continue

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Remove the initiating user's own ID from the target list before calling DeleteUsers
  2. Have another owner/admin perform the deletion if the goal really is to delete that account

Example fix

// before
allUsers := listAccountUserIDs(accountID) // includes current admin
deleteUsers(ctx, accountID, adminID, allUsers)

// after
targets := filterOut(allUsers, adminID) // never delete self
deleteUsers(ctx, accountID, adminID, targets)
Defensive patterns

Strategy: validation

Validate before calling

func excludeSelf(targets []string, initiator string) []string {
    out := targets[:0]
    for _, t := range targets {
        if t != initiator { out = append(out, t) }
    }
    return out
}

targets = excludeSelf(targets, initiatorUserID)

Try / catch

err := am.DeleteUsers(ctx, accountID, initiatorID, targets)
if err != nil && strings.Contains(err.Error(), "self deletion is not allowed") {
    // remove the initiator's ID from targets and retry the remaining batch
}

Prevention

When it happens

Trigger: Calling the delete-users API/handler with the caller's own user ID in the targetUserIDs list, e.g. an admin picking themselves in a bulk delete, or a script that passes "all users" including the current one.

Common situations: Dashboard bulk-select that includes the logged-in admin; cleanup scripts that enumerate every user of the account; inviting user to select themselves accidentally.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/4fe0ba9e0efa647b. Report an issue: GitHub.