{"record":{"id":"6016ce9ba8e09e1a","repo":"apache/pulsar","slug":"resourcegroup-already-exists","errorCode":null,"errorMessage":"ResourceGroup already exists","messagePattern":"ResourceGroup already exists","errorType":"http","errorClass":"RestException","httpStatus":409,"severity":"warning","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/ResourceGroupsBase.java","lineNumber":112,"sourceCode":"    }\n\n    protected void internalCreateResourceGroup(String rgName, ResourceGroup rgConfig) {\n        rgConfig.setPublishRateInMsgs(rgConfig.getPublishRateInMsgs() == null\n                ? -1 : rgConfig.getPublishRateInMsgs());\n        rgConfig.setPublishRateInBytes(rgConfig.getPublishRateInBytes() == null\n                ? -1 : rgConfig.getPublishRateInBytes());\n        rgConfig.setDispatchRateInMsgs(rgConfig.getDispatchRateInMsgs() == null\n                ? -1 : rgConfig.getDispatchRateInMsgs());\n        rgConfig.setDispatchRateInBytes(rgConfig.getDispatchRateInBytes() == null\n                ? -1 : rgConfig.getDispatchRateInBytes());\n        try {\n            resourceGroupResources().createResourceGroup(rgName, rgConfig);\n            log.info().attr(\"resourceGroup\", rgName).log(\"Created ResourceGroup\");\n        } catch (MetadataStoreException.AlreadyExistsException e) {\n            log.warn()\n                    .attr(\"resourceGroup\", rgName)\n                    .log(\"Failed to create ResourceGroup - already exists\");\n            throw new RestException(Response.Status.CONFLICT, \"ResourceGroup already exists\");\n        } catch (Exception e) {\n            log.error()\n                    .attr(\"resourceGroup\", rgName)\n                    .exception(e)\n                    .log(\"Failed to create ResourceGroup\");\n            throw new RestException(e);\n        }\n\n    }\n    protected void internalCreateOrUpdateResourceGroup(String rgName, ResourceGroup rgConfig) {\n        try {\n            validateSuperUserAccess();\n            checkNotNull(rgConfig);\n            /*\n             * see if ResourceGroup exists and treat the request as a update if it does.\n             */\n            boolean rgExists = false;\n            try {","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/ResourceGroupsBase.java#L94-L130","documentation":"Returned with HTTP 409 CONFLICT when creating a resource group fails because one with the same name already exists in the metadata store (MetadataStoreException.AlreadyExistsException). The handler logs 'Failed to create ResourceGroup - already exists' at WARN and maps it to Response.Status.CONFLICT with message 'ResourceGroup already exists'. It is a name-collision signal, not an infrastructure failure.","triggerScenarios":"PUT/POST create of /admin/v3/resourcegroups/{rgName} when the metadata store already contains an entry for rgName — e.g. a race between two create requests, or a create issued for an existing group via the create-only path (internalCreateResourceGroup).","commonSituations":"Two admins or automation scripts creating the same group concurrently; re-running a bootstrap script without idempotency; using the create endpoint expecting upsert semantics.","solutions":["Use the create-or-update (upsert) path instead of the create-only call if overwriting is acceptable.","Check existence first (GET the resource group) and skip or update instead of creating.","Catch the 409 on the client and fall back to an update operation.","If caused by a race, serialize provisioning of resource groups (one actor per name)."],"exampleFix":"// before\nadmin.resourcegroups().createResourceGroup(rgName, rg); // 409 if exists\n// after\ntry {\n    admin.resourcegroups().createResourceGroup(rgName, rg);\n} catch (PulsarAdminException e) {\n    if (e.getStatusCode() == 409) {\n        admin.resourcegroups().updateResourceGroup(rgName, rg); // idempotent upsert\n    } else {\n        throw e;\n    }\n}","handlingStrategy":"fallback","validationCode":"// pre-check existence\nboolean exists;\ntry { admin.resourcegroups().getResourceGroup(rgName); exists = true; }\ncatch (PulsarAdminException e) { exists = e.getStatusCode() != 404; }","typeGuard":"null","tryCatchPattern":"try {\n    admin.resourcegroups().createResourceGroup(rgName, rg);\n} catch (PulsarAdminException e) {\n    if (e.getStatusCode() == 409) admin.resourcegroups().updateResourceGroup(rgName, rg); // upsert fallback\n    else throw e;\n}","preventionTips":["Prefer the upsert endpoint over create-only when idempotency is desired.","Check existence before creating in provisioning scripts.","Serialize creation of same-named groups across automation."],"tags":["rest-api","conflict","duplicate-resource","resourcegroups"],"backgroundTag":"resource-already-exists","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}