apache/pulsar · error · PulsarAdminException

Resource group already exists:${rgName}

Error message

Resource group already exists:${rgName}

What it means

Thrown as PulsarAdminException when creating a resource group whose name already exists in the broker's resource-group map. Resource group names must be unique, so a duplicate create is rejected instead of overwriting the existing config.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/resourcegroup/ResourceGroupService.java:816

        final long periodInSecs = pulsar.getConfiguration().getResourceUsageTransportPublishIntervalInSecs();
        this.aggregateLocalUsagePeriodInSeconds = this.resourceUsagePublishPeriodInSeconds = periodInSecs;
        // if any tenant/namespace registrations already exist, maybeStartSchedulers() will start the schedulers now.
        maybeStartSchedulers();
    }

    private void checkRGCreateParams(String rgName, org.apache.pulsar.common.policies.data.ResourceGroup rgConfig)
      throws PulsarAdminException {
        if (rgConfig == null) {
            throw new IllegalArgumentException("ResourceGroupCreate: Invalid null ResourceGroup config");
        }

        if (rgName.isEmpty()) {
            throw new IllegalArgumentException("ResourceGroupCreate: can't create resource group with an empty name");
        }

        ResourceGroup rg = getResourceGroupInternal(rgName);
        if (rg != null) {
            throw new PulsarAdminException("Resource group already exists:" + rgName);
        }
    }
    @Getter
    private final PulsarService pulsar;

    protected final ResourceQuotaCalculator quotaCalculator;
    private ResourceUsageTransportManager resourceUsageTransportManagerMgr;

    // rgConfigListener is used only through its side effects in the ctors, to set up RG/NS loading in config-listeners.
    private final ResourceGroupConfigListener rgConfigListener;

    // Given a RG-name, get the resource-group
    private ConcurrentHashMap<String, ResourceGroup> resourceGroupsMap = new ConcurrentHashMap<>();

    // Given a tenant-name, record its associated resource-group
    private ConcurrentHashMap<String, ResourceGroup> tenantToRGsMap = new ConcurrentHashMap<>();

    // Given a qualified NS-name (i.e., in "tenant/namespace" format), record its associated resource-group

View on GitHub (pinned to 820761864e)

Solutions

  1. Check existence first (getResourceGroupInternal / admin GET) and update instead of create if present
  2. Use an update API (or create-or-update pattern) for idempotent provisioning
  3. Serialize provisioning so concurrent jobs don't race
  4. Catch PulsarAdminException with 'already exists' in the message and treat as success in retry logic

Example fix

// before
admin.resourcegroups().createResourceGroup("rg1", rg); // fails on rerun
// after
try {
    admin.resourcegroups().createResourceGroup("rg1", rg);
} catch (PulsarAdminException e) {
    if (!String.valueOf(e.getMessage()).contains("already exists")) throw e;
    admin.resourcegroups().updateResourceGroup("rg1", rg);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (admin.resourcegroups().getResourceGroup(rgName) != null) {
    admin.resourcegroups().updateResourceGroup(rgName, rgConfig);
} else {
    admin.resourcegroups().createResourceGroup(rgName, rgConfig);
}

Try / catch

try {
    admin.resourcegroups().createResourceGroup(rgName, rgConfig);
} catch (PulsarAdminException e) {
    if (String.valueOf(e.getMessage()).startsWith("Resource group already exists")) {
        admin.resourcegroups().updateResourceGroup(rgName, rgConfig);
    } else throw e;
}

Prevention

When it happens

Trigger: Calling createResourceGroup with a name that was previously created — re-running an initialization script, two services racing to bootstrap the same group, or a retry after a timeout where the first attempt actually succeeded.

Common situations: Idempotency issues in deploy scripts; concurrent provisioning jobs; migrating config where the group already exists on the target cluster.

Related errors


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