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
- Call the endpoint with the base topic name without the '-partition-N' suffix
- Strip the partition suffix before constructing the admin URL
- 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
- Never pass concrete partition names to partition-management endpoints
- Normalize names via TopicName and use getPartitionedTopicName()
- Document that partitions are managed only via the parent topic
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
- Partitioned Topic Name should not contain '-partition-'
- {e.getMessage()}
- cluster data is required
- Cluster already exists
- Peer cluster ${peerCluster} does not exist
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/163a2cebb24f24db.
Report an issue: GitHub.