apache/pulsar · warning · RestException

Partitioned Topic Name should not contain '-partition-'

Error message

Partitioned Topic Name should not contain '-partition-'

What it means

The updatePartitionedTopic (create/update partitions) admin endpoint rejects a topicName that already includes '-partition-N', because partition counts can only be managed on the base partitioned topic. It returns HTTP 412 PRECONDITION_FAILED.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/PersistentTopics.java:988

    })
    public void updatePartitionedTopic(
            @Suspended final AsyncResponse asyncResponse,
            @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,
            @QueryParam("updateLocalTopicOnly") @DefaultValue("false") boolean updateLocalTopic,
            @Parameter(description = "Whether leader broker redirected this call to this broker. For internal use.")
            @QueryParam("authoritative") @DefaultValue("false") boolean authoritative,
            @QueryParam("force") @DefaultValue("false") boolean force,
            @RequestBody(description = "The number of partitions for the topic",
                    required = true, content = @Content(schema = @Schema(type = "integer", defaultValue = "0")))
                    int numPartitions) {
        validateTopicName(tenant, namespace, encodedTopic);
        if (topicName.isPartitioned()) {
            throw new RestException(Response.Status.PRECONDITION_FAILED,
                    "Partitioned Topic Name should not contain '-partition-'");
        }
        validateTopicPolicyOperationAsync(topicName, PolicyName.PARTITION, PolicyOperation.WRITE)
                .thenCompose(__ -> internalUpdatePartitionedTopicAsync(numPartitions, updateLocalTopic, force))
                .thenAccept(__ -> {
                    log.info()
                            .attr("topic", topicName)
                            .attr("numPartitions", numPartitions)
                            .log("Updated topic partitions");
                    asyncResponse.resume(Response.noContent().build());
                })
                .exceptionally(ex -> {
                    if (isNot307And404Exception(ex) && !isConflictException(ex)) {
                        log.error()
                                .attr("topic", topicName)
                                .attr("numPartitions", numPartitions)
                                .exception(ex)
                                .log("Failed to update partitions");

View on GitHub (pinned to 820761864e)

Solutions

  1. Call the endpoint with the base topic name without the '-partition-N' suffix
  2. Strip the partition suffix before constructing the admin URL
  3. List namespace topics and use the non-partition-suffixed name as the partitioned topic handle

Example fix

// before
admin.topics().updatePartitionedTopic("persistent://public/default/my-topic-partition-0", 5);
// after
admin.topics().updatePartitionedTopic("persistent://public/default/my-topic", 5);
Defensive patterns

Strategy: validation

Validate before calling

if (topic.matches(".*-partition-\\d+$")) throw new IllegalArgumentException("Pass base topic without -partition-N: " + topic);

Type guard

boolean isPartitionHandle(String t) { return t != null && t.matches(".*-partition-\\d+$"); }

Try / catch

try { admin.topics().updatePartitionedTopic(base, n); } catch (PulsarAdminException e) { if (e.getStatusCode() == 412) { /* use base topic */ } }

Prevention

When it happens

Trigger: PUT/POST to /admin/v2/persistent/{tenant}/{namespace}/{topic}/partitions where topic contains '-partition-N' (e.g. my-topic-partition-0).

Common situations: Automation that captured a concrete partition name from a client URL or stats and passed it to the partition-management API.

Related errors


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