apache/pulsar · warning · RestException

ResourceGroup is in use

Error message

ResourceGroup is in use

What it means

Returned with HTTP 412 PRECONDITION_FAILED when deleting a resource group that is still referenced by at least one tenant or namespace. internalDeleteResourceGroup calls internalCheckRgInUse first; if true it throws this RestException with 'ResourceGroup is in use' instead of deleting, protecting namespaces that still depend on the group's rate limits. It is an expected guard, not an infrastructure fault.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/ResourceGroupsBase.java:192

                    .attr("resourceGroup", rgName)
                    .exceptionMessage(e)
                    .log("Failed to get tenant/namespace list");
            throw new RestException(e);
        }
        return false;
    }

    protected void internalDeleteResourceGroup(String rgName) {
        /*
         * need to walk the namespaces and make sure it is not in use
         */
        try {
            validateSuperUserAccess();
            /*
             * walk the namespaces and make sure it is not in use.
             */
            if (internalCheckRgInUse(rgName)) {
                throw new RestException(Response.Status.PRECONDITION_FAILED, "ResourceGroup is in use");
            }
            resourceGroupResources().deleteResourceGroup(rgName);
            log.info().attr("resourceGroup", rgName).log("Deleted ResourceGroup");
        } catch (Exception e) {
            log.error()
                    .attr("resourceGroup", rgName)
                    .exception(e)
                    .log("Failed to delete ResourceGroup .");
            throw new RestException(e);
        }
    }
}

View on GitHub (pinned to 820761864e)

Solutions

  1. Find namespaces referencing the group (list tenants/namespaces and check their policies).
  2. Update each namespace to remove or replace the resourceGroup reference.
  3. Retry the delete once no namespaces reference the group.
  4. If the reference is stale (namespace already deleted), clean up the leftover policy data and retry.

Example fix

// before
admin.resourcegroups().deleteResourceGroup(rgName); // 412 if in use
// after
try {
    admin.resourcegroups().deleteResourceGroup(rgName);
} catch (PulsarAdminException e) {
    if (e.getStatusCode() == 412) {
        namespaces.forEach(ns -> admin.namespaces().removeResourceGroup(ns)); // detach first
        admin.resourcegroups().deleteResourceGroup(rgName);
    } else { throw e; }
}
Defensive patterns

Strategy: validation

Validate before calling

// check references before deleting
for (String ns : listAllNamespaces(admin)) {
    if (rgName.equals(getResourceGroupOf(ns))) throw new IllegalStateException(ns + " still uses " + rgName);
}

Type guard

null

Try / catch

try {
    admin.resourcegroups().deleteResourceGroup(rgName);
} catch (PulsarAdminException e) {
    if (e.getStatusCode() == 412) detachFromAllNamespaces(rgName); // then retry
    else throw e;
}

Prevention

When it happens

Trigger: DELETE /admin/v3/resourcegroups/{rgName} while any namespace policy still sets resourceGroup=rgName (e.g. via namespace publish/dispatch rate config referencing the group).

Common situations: Tearing down resource groups before migrating namespaces off them; forgotten namespace policies after offboarding an app; automation deleting groups referenced by templates.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/eeb61b2199d26285. Report an issue: GitHub.