apache/pulsar · error · org.apache.pulsar.broker.admin.RestException
Partitioned Topic Name should not contain '-partition-'
Error message
Partitioned Topic Name should not contain '-partition-'
What it means
Thrown by validatePartitionedTopicName when the topic local name already contains the internal partition suffix '-partition-N'. Partitioned topic names must be the base name; partition members (base-partition-0, base-partition-1, ...) are created automatically by the broker and cannot be addressed when creating a partitioned topic. Returns HTTP 412.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/AdminResource.java:286
} catch (IllegalArgumentException e) {
log.warn().attr("topic", topicName).log("Forbidden to create topic with an invalid name");
throw new RestException(Status.PRECONDITION_FAILED, e.getMessage());
}
}
protected void validatePersistentTopicName(String tenant, String namespace, String encodedTopic) {
validateTopicName(tenant, namespace, encodedTopic);
if (topicName.getDomain() != TopicDomain.persistent) {
throw new RestException(Status.NOT_ACCEPTABLE, "Need to provide a persistent topic name");
}
}
protected void validatePartitionedTopicName(String tenant, String namespace, String encodedTopic) {
// first, it has to be a validate topic name
validateTopicName(tenant, namespace, encodedTopic);
// second, "-partition-" is not allowed
if (encodedTopic.contains(TopicName.PARTITIONED_TOPIC_SUFFIX)) {
throw new RestException(Status.PRECONDITION_FAILED,
"Partitioned Topic Name should not contain '-partition-'");
}
}
protected CompletableFuture<Void> validatePartitionedTopicMetadataAsync() {
return pulsar().getBrokerService().fetchPartitionedTopicMetadataAsync(topicName)
.thenAccept(metadata -> {
if (metadata.partitions < 1) {
throw new RestException(Status.CONFLICT, "Topic is not partitioned topic");
}
});
}
protected WorkerService validateAndGetWorkerService() {
try {
return pulsar().getWorkerService();
} catch (UnsupportedOperationException e) {
throw new RestException(Status.CONFLICT, e.getMessage());View on GitHub (pinned to 820761864e)
Solutions
- Strip the '-partition-N' suffix and use the base topic name when calling the partitioned-topic create API.
- Filter out names containing '-partition-' from topic lists before re-creating them as partitioned topics.
- If you intended to change partition count of an existing partitioned topic, use updatePartitionedTopic on the base name instead.
- Reference the partitioned topic by its base name in clients; producers auto-discover partitions.
Example fix
// before
admin.topics().createPartitionedTopic("my-topic-partition-0", 4);
// after
admin.topics().createPartitionedTopic("my-topic", 4); Defensive patterns
Strategy: validation
Validate before calling
// Java: strip partition suffix before partitioned-topic operations
static String baseTopicName(String local) {
int i = local.lastIndexOf("-partition-");
return i > 0 ? local.substring(0, i) : local;
} Type guard
static boolean isPartitionMember(String local) {
return local.matches(".*-partition-\\d+$");
} Try / catch
try {
admin.topics().createPartitionedTopic(base, n);
} catch (PulsarAdminException e) {
if (e.getStatusCode() == 412 && e.getMessage().contains("-partition-")) {
base = baseTopicName(base); // retry with base name
}
} Prevention
- When iterating topic lists, filter or normalize -partition-N names to their base.
- Never address individual partitions via the partitioned-topic admin APIs.
- Remember producers reach partitions automatically via the base topic name.
When it happens
Trigger: Calling createPartitionedTopic (PUT /admin/v2/persistent/tenant/ns/my-topic-partition-0 with numPartitions) on a name that includes '-partition-' — i.e. trying to partition an individual partition of another topic.
Common situations: Scripts iterating a topic list (which includes individual partitions) and calling create-partitioned on each; users copying a partition member name from a client URI or logs; automation that lists topics via topics() and re-creates them as partitioned.
Related errors
- Topic name is not valid
- Exceed maximum number of topics in namespace.
- Invalid value for message TTL
- interval must be greater than or equal to 0
- maxProducersPerTopic must be 0 or more
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/3515120c795b6a8a.
Report an issue: GitHub.