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

  1. Strip the '-partition-N' suffix and use the base topic name when calling the partitioned-topic create API.
  2. Filter out names containing '-partition-' from topic lists before re-creating them as partitioned topics.
  3. If you intended to change partition count of an existing partitioned topic, use updatePartitionedTopic on the base name instead.
  4. 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 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


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