apache/pulsar · warning · RestException

numInitialSegments must be >= 1

Error message

numInitialSegments must be >= 1

What it means

HTTP 412 thrown by the scalable-topic create REST endpoint when the query parameter numInitialSegments is less than 1. A scalable topic must be created with at least one initial segment, so zero or negative values are rejected as invalid configuration before any metadata is written.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/ScalableTopics.java:189

            @Parameter(description = "Specify the tenant", required = true)
            @PathParam("tenant") String tenant,
            @Parameter(description = "Specify the namespace", required = true)
            @PathParam("namespace") String namespace,
            @Parameter(description = "Specify topic name", required = true)
            @PathParam("topic") @Encoded String encodedTopic,
            @Parameter(description = "Number of initial segments")
            @QueryParam("numInitialSegments") @DefaultValue("1") int numInitialSegments,
            @RequestBody(description = "Key value pair properties for the topic metadata")
            Map<String, String> properties) {
        validateNamespaceName(tenant, namespace);
        String decodedTopic = Codec.decode(encodedTopic);
        TopicName tn = TopicName.get(TopicDomain.topic.value(), namespaceName, decodedTopic);
        validateCreateTopic(tn);

        validateNamespaceOperationAsync(namespaceName, NamespaceOperation.CREATE_TOPIC)
                .thenCompose(__ -> {
                    if (numInitialSegments < 1) {
                        throw new RestException(Response.Status.fromStatusCode(412),
                                "numInitialSegments must be >= 1");
                    }
                    Map<String, String> props = properties != null ? properties : Map.of();
                    ScalableTopicMetadata metadata = ScalableTopicController.createInitialMetadata(
                            numInitialSegments,
                            pulsar().getConfiguration().getScalableTopicEntryBucketBudget(),
                            pulsar().getConfiguration().getScalableTopicEntryBucketMaxPerSegment(),
                            props);
                    return resources().createScalableTopicAsync(tn, metadata)
                            .thenCompose(ignored -> createInitialSegmentTopicsAsync(tn, metadata));
                })
                .thenAccept(__ -> {
                    log.info().attr("clientAppId", clientAppId()).attr("topic", tn)
                            .attr("numInitialSegments", numInitialSegments)
                            .log("Created scalable topic");
                    asyncResponse.resume(Response.noContent().build());
                })
                .exceptionally(ex -> {

View on GitHub (pinned to 820761864e)

Solutions

  1. Set the numInitialSegments query parameter to a value >= 1, or omit it (defaults to 1).
  2. Fix the calling script/tool so an unset value resolves to the default (1) rather than 0 or -1.
  3. Validate the segment count client-side before invoking the create call.

Example fix

// before
curl -X PUT '.../scalable-topics/tn/ns/my-topic?numInitialSegments=0'
// after
curl -X PUT '.../scalable-topics/tn/ns/my-topic?numInitialSegments=4'
Defensive patterns

Strategy: validation

Validate before calling

if (!Number.isInteger(numInitialSegments) || numInitialSegments < 1) {
  throw new Error('numInitialSegments must be an integer >= 1');
}

Type guard

const isValidSegmentCount = (n) => Number.isInteger(n) && n >= 1;

Try / catch

try {
  await admin.scalableTopics().createScalableTopic(tenant, ns, topic, numInitialSegments);
} catch (e) {
  if (e.status === 412) { /* fix segment count and retry */ }
  throw e;
}

Prevention

When it happens

Trigger: Calling PUT /admin/v2/scalable-topics/{tenant}/{namespace}/{topic} with numInitialSegments=0 or a negative number.

Common situations: Automation scripts computing segment counts from an empty or misparsed config value; shell scripts omitting a default and passing 0; tools that pass -1 as a sentinel for 'unspecified' instead of omitting the parameter.

Understand the failure class

Background: "must be positive", "Invalid value": how libraries reject invalid parameter values (ValueError, ArgumentError, INVALID_PARAMETER_VALUE) — this error's family across 28 libraries.

Related errors


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