apache/dolphinscheduler · error · ServiceException

DELETE_TENANT_BY_ID_FAIL_TENANTS

DELETE_TENANT_BY_ID_FAIL_TENANTS

Error message

DELETE_TENANT_BY_ID_FAIL_TENANTS: {tenantCount} tenants are using this queue, delete failed

What it means

QueueServiceImpl.deleteQueueById throws ServiceException(Status.DELETE_TENANT_BY_ID_FAIL_TENANTS, tenantCount) when tenants still reference the queue: tenantDao.queryTenantListByQueueId(queue.getId()) returns a non-empty list. The delete is a referential-integrity guard — queues in use by tenants cannot be removed. The message interpolates the number of blocking tenants.

Source

Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/QueueServiceImpl.java:232

     * @throws Exception exception
     */
    @Override
    public void deleteQueueById(User loginUser, int id) throws Exception {

        if (!canOperatorPermissions(loginUser, null, AuthorizationType.TENANT, TENANT_DELETE)) {
            throw new ServiceException(Status.USER_NO_OPERATION_PERM);
        }

        Queue queue = queueDao.queryById(id);
        if (Objects.isNull(queue)) {
            log.error("Queue does not exist");
            throw new ServiceException(Status.QUEUE_NOT_EXIST);
        }

        List<Tenant> tenantList = tenantDao.queryTenantListByQueueId(queue.getId());
        if (CollectionUtils.isNotEmpty(tenantList)) {
            log.warn("Delete queue failed, because there are {} tenants using it.", tenantList.size());
            throw new ServiceException(Status.DELETE_TENANT_BY_ID_FAIL_TENANTS, tenantList.size());
        }

        List<User> userList = userDao.queryUserListByQueue(queue.getQueueName());
        if (CollectionUtils.isNotEmpty(userList)) {
            log.warn("Delete queue failed, because there are {} users using it.", userList.size());
            throw new ServiceException(Status.DELETE_QUEUE_BY_ID_FAIL_USERS, userList.size());
        }

        if (!queueDao.deleteById(id)) {
            throw new ServiceException(Status.DELETE_QUEUE_BY_ID_ERROR);
        }

    }

    /**
     * verify queue and queueName
     *
     * @param queue queue

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Reassign the tenants to another queue (update each tenant's queue) via the tenant management API/UI, then retry the delete.
  2. List the blocking tenants (the error reports the count; query t_ds_tenant WHERE queue_id = <id>) and update them in bulk.
  3. If the queue truly should not be referenced, migrate the tenants' queue_id in the database during a maintenance window, then delete the queue.

Example fix

// before: delete while tenants still use queue
DELETE /dolphinscheduler/queues/7 -> DELETE_TENANT_BY_ID_FAIL_TENANTS (3 tenants)

// after: reassign tenants first
tenantService.updateTenant(loginUser, tenantId, ..., newQueueId); // for each of the 3 tenants
deleteQueueById(loginUser, 7) -> succeeds
Defensive patterns

Strategy: validation

Validate before calling

// check tenant references before deleting
List<Tenant> tenants = tenantDao.queryTenantListByQueueId(id);
if (!tenants.isEmpty()) {
    throw new IllegalStateException("Queue " + id + " still used by " + tenants.size() + " tenant(s)");
}

Try / catch

try {
    queueService.deleteQueueById(loginUser, id);
} catch (ServiceException e) {
    if (Status.DELETE_TENANT_BY_ID_FAIL_TENANTS.getCode() == e.getCode()) {
        // reassign tenants then retry
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling DELETE queue/{id} while one or more rows in t_ds_tenant have queue_id equal to the target queue's id; deleting a default/production YARN queue still assigned to tenants.

Common situations: Cleaning up old YARN queues that are still the default for tenant(s); importing tenant data pointing at the queue; multi-tenant environments where a queue remains assigned after team offboarding.

Related errors


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/9ab146a3a021e44f. Report an issue: GitHub.