{"record":{"id":"820d4907305f67ec","repo":"apache/pulsar","slug":"resourcegroupcreate-invalid-null-resourcegroup-co","errorCode":null,"errorMessage":"ResourceGroupCreate: Invalid null ResourceGroup config","messagePattern":"ResourceGroupCreate: Invalid null ResourceGroup config","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/resourcegroup/ResourceGroupService.java","lineNumber":807,"sourceCode":"                calculateQuotaPeriodicTask = null;\n            }\n            log.info(\"Stopped ResourceGroupService periodic tasks because no registrations remain\");\n        }\n    }\n\n    private void initialize() {\n        // Store the configured interval. Do not start periodic tasks unconditionally here.\n        // Schedulers are started by maybeStartSchedulers() when the first tenant/namespace is registered.\n        final long periodInSecs = pulsar.getConfiguration().getResourceUsageTransportPublishIntervalInSecs();\n        this.aggregateLocalUsagePeriodInSeconds = this.resourceUsagePublishPeriodInSeconds = periodInSecs;\n        // if any tenant/namespace registrations already exist, maybeStartSchedulers() will start the schedulers now.\n        maybeStartSchedulers();\n    }\n\n    private void checkRGCreateParams(String rgName, org.apache.pulsar.common.policies.data.ResourceGroup rgConfig)\n      throws PulsarAdminException {\n        if (rgConfig == null) {\n            throw new IllegalArgumentException(\"ResourceGroupCreate: Invalid null ResourceGroup config\");\n        }\n\n        if (rgName.isEmpty()) {\n            throw new IllegalArgumentException(\"ResourceGroupCreate: can't create resource group with an empty name\");\n        }\n\n        ResourceGroup rg = getResourceGroupInternal(rgName);\n        if (rg != null) {\n            throw new PulsarAdminException(\"Resource group already exists:\" + rgName);\n        }\n    }\n    @Getter\n    private final PulsarService pulsar;\n\n    protected final ResourceQuotaCalculator quotaCalculator;\n    private ResourceUsageTransportManager resourceUsageTransportManagerMgr;\n\n    // rgConfigListener is used only through its side effects in the ctors, to set up RG/NS loading in config-listeners.","sourceCodeStart":789,"sourceCodeEnd":825,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/resourcegroup/ResourceGroupService.java#L789-L825","documentation":"ResourceGroupService's constructor validates create parameters via checkRGCreateParams and throws IllegalArgumentException if the ResourceGroup config object is null. A resource group cannot be created without its configuration (dispatch/subscribe rate limits), so null is rejected immediately.","triggerScenarios":"Passing a null ResourceGroup config to the resource-group creation path (admin createResourceGroup call that supplies no policy object), usually due to unmarshalled/empty request bodies.","commonSituations":"REST client sending an empty or malformed JSON body to the resourcegroups admin endpoint; SDK method invoked with null config; deserialization silently producing null.","solutions":["Supply a valid ResourceGroup config object with at least dispatch/subscribe rate limits set","Check the REST request body is non-empty, valid JSON matching the ResourceGroup schema","In client code, null-check the config before calling createResourceGroup","Verify admin SDK version compatibility — malformed payloads may deserialize to null"],"exampleFix":"// before\nadmin.resourcegroups().createResourceGroup(\"rg1\", null);\n// after\nResourceGroup rg = new ResourceGroup();\nrg.setDispatchRate(new DispatchRate());\nrg.setSubscribeRate(new SubscribeRate());\nadmin.resourcegroups().createResourceGroup(\"rg1\", rg);","handlingStrategy":"validation","validationCode":"if (rgConfig == null) {\n    throw new IllegalArgumentException(\"ResourceGroup config must be provided\");\n}","typeGuard":"boolean validRgConfig(ResourceGroup rg) {\n    return rg != null && rg.getDispatchRate() != null;\n}","tryCatchPattern":"try {\n    createResourceGroupPath(name, config);\n} catch (IllegalArgumentException e) {\n    if (String.valueOf(e.getMessage()).contains(\"Invalid null ResourceGroup config\")) {\n        // fix request body and retry\n    } else throw e;\n}","preventionTips":["Always build a fully-populated ResourceGroup before create calls","Validate REST request bodies server-side before reaching the service","Log/inspect raw request bodies when deserialization may yield null"],"tags":["pulsar","admin-api","validation","illegal-argument"],"backgroundTag":"missing-required-parameter","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"}