apache/pulsar · info · RestException

cluster data is required

Error message

cluster data is required

What it means

createCluster validates that a ClusterData payload accompanies the PUT /admin/v2/clusters/{cluster} request. The cluster name comes from the path, but the body must contain the cluster configuration (service URLs, etc.); if the body is missing, null, or deserializes to null, it throws HTTP 400 BAD_REQUEST with 'cluster data is required'.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/ClustersBase.java:174

            required = true,
            content = @Content(
                mediaType = MediaType.APPLICATION_JSON,
                examples = @ExampleObject(
                    value = """
                            {
                               "serviceUrl": "http://pulsar.example.com:8080",
                               "brokerServiceUrl": "pulsar://pulsar.example.com:6651"
                            }
                            """
                )
            )
        ) ClusterDataImpl clusterData) {
        validateBothSuperuserAndClusterOperation(cluster, ClusterOperation.CREATE_CLUSTER)
                .thenCompose(__ -> validatePoliciesReadOnlyAccessAsync())
                .thenCompose(__ -> {
                    NamedEntity.checkName(cluster);
                    if (clusterData == null) {
                        throw new RestException(Status.BAD_REQUEST, "cluster data is required");
                    }
                    try {
                        clusterData.checkPropertiesIfPresent();
                    } catch (IllegalArgumentException ex) {
                        throw new RestException(Status.BAD_REQUEST, ex.getMessage());
                    }
                    return clusterResources().getClusterAsync(cluster);
                }).thenCompose(clusterOpt -> {
                    if (clusterOpt.isPresent()) {
                        throw new RestException(Status.CONFLICT, "Cluster already exists");
                    }
                    return clusterResources().createClusterAsync(cluster, clusterData);
                }).thenAccept(__ -> {
                    log.info().attr("cluster", cluster).log("Created cluster");
                    asyncResponse.resume(Response.ok().build());
                }).exceptionally(ex -> {
                    log.error()
                            .attr("cluster", cluster)

View on GitHub (pinned to 820761864e)

Solutions

  1. Send a complete ClusterData JSON body, e.g. {"serviceUrl":"http://broker:8080","serviceUrlTls":"https://broker:8443","brokerServiceUrl":"pulsar://broker:6650","brokerServiceUrlTls":"pulsar+ssl://broker:6651"}.
  2. Ensure the request Content-Type is application/json and the body is non-empty; with curl use -H 'Content-Type: application/json' -d '{...}'.
  3. Prefer the Java/CLI client (pulsar-admin clusters create) which constructs ClusterData for you, avoiding hand-rolled REST bodies.

Example fix

// before: empty body -> 400
curl -X PUT http://broker:8080/admin/v2/clusters/us-west -H 'Content-Type: application/json'
// after: supply cluster data
curl -X PUT http://broker:8080/admin/v2/clusters/us-west -H 'Content-Type: application/json' \
  -d '{"serviceUrl":"http://broker:8080","brokerServiceUrl":"pulsar://broker:6650"}'
Defensive patterns

Strategy: validation

Validate before calling

// validate the payload before PUT /clusters/{cluster}
if (clusterData == null || clusterData.getServiceUrl() == null
        || clusterData.getServiceUrl().isEmpty()) {
    throw new IllegalArgumentException("cluster data with serviceUrl is required");
}

Try / catch

try {
    admin.clusters().createCluster(clusterName, clusterData);
} catch (PulsarAdminException.BadRequestException e) {
    if ("cluster data is required".equals(e.getMessage())) {
        log.error("PUT sent without a ClusterData body");
    }
}

Prevention

When it happens

Trigger: PUT /admin/v2/clusters/{cluster} with an empty body, no Content-Type/application-json, or a JSON body that deserializes to a null ClusterData object (e.g. literal 'null' body).

Common situations: Using curl without -d/--data or with an empty -d '{}'-less body; CLI/SDK calls where the cluster data argument is omitted; scripting against the REST API with wrong Content-Type so the body is dropped; proxy/gateway stripping the request body.

Related errors


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