{"record":{"id":"6d13ab9bbcf68225","repo":"apache/pulsar","slug":"another-partition-exists-for-topicname","errorCode":null,"errorMessage":"Another partition exists for [${topicName}].","messagePattern":"Another partition exists for \\[(.+?)\\]\\.","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentTopic.java","lineNumber":3836,"sourceCode":"                                    for (int i = 0; i < metadata.partitions; i++) {\n                                        persistentTopicExists.add(brokerService.getPulsar()\n                                                .getPulsarResources().getTopicResources()\n                                                .persistentTopicExists(topicName.getPartition(i)));\n                                    }\n                                    List<CompletableFuture<Boolean>> unmodifiablePersistentTopicExists =\n                                            Collections.unmodifiableList(persistentTopicExists);\n                                    return FutureUtil.waitForAll(unmodifiablePersistentTopicExists)\n                                            .thenCompose(unused -> {\n                                                // make sure all sub partitions were deleted after all future complete\n                                                Optional<Boolean> anyExistPartition = unmodifiablePersistentTopicExists\n                                                        .stream()\n                                                        .map(CompletableFuture::join)\n                                                        .filter(topicExist -> topicExist)\n                                                        .findAny();\n                                                if (anyExistPartition.isPresent()) {\n                                                    log.info(\"Delete topic metadata failed because \"\n                                                            + \"another partition exists\");\n                                                    throw new UnsupportedOperationException(\n                                                            String.format(\"Another partition exists for [%s].\",\n                                                                    topicName));\n                                                } else {\n                                                    try {\n                                                        return brokerService.getPulsar().getAdminClient().topics()\n                                                                .deletePartitionedTopicAsync(topicName.toString());\n                                                    } catch (PulsarServerException e) {\n                                                        log.info()\n                                                                .exception(e)\n                                                                .log(\"Delete topic metadata failed due to failed to\"\n                                                                        + \"get internal admin client.\");\n                                                        return CompletableFuture.failedFuture(e);\n                                                    }\n                                                }\n                                            });\n                                }))\n                            );\n                    }","sourceCodeStart":3818,"sourceCodeEnd":3854,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentTopic.java#L3818-L3854","documentation":"When deleting a partitioned topic, the broker deletes each partition first and then removes the partitioned-topic metadata. Before deleting metadata it checks whether any partition still exists; if at least one partition check returns true, deletion is aborted with UnsupportedOperationException because removing the parent metadata while partitions remain would orphan them. The error protects the invariants of partitioned-topic bookkeeping in metadata storage.","triggerScenarios":"Calling admin topics().deletePartitionedTopic() (or internal metadata delete) after the per-partition existence checks found at least one partition still present — e.g. partial partition deletion left partitions behind, or the existence check futures resolved true due to stale caches/timing.","commonSituations":"Retrying a previously failed delete where some partitions were removed; topic list/lookup caches briefly reporting the partitions as existing; delete of a partitioned topic whose partitions are being recreated concurrently by a producer; namespace/topic policy propagation delays in geo-replicated clusters.","solutions":["Wait for partition deletion to fully complete (all partitions removed from all brokers) and retry deletePartitionedTopic","Call deletePartitionedTopic with deleteSchema=false as appropriate and ensure no producers/consumers are recreating partitions, then retry","Force-delete remaining individual partitions first (topics().delete per partition), then delete the partitioned topic metadata","Check broker logs ('Delete topic metadata failed because another partition exists') and clear stale topic list caches if partitions are actually gone"],"exampleFix":"// before\nadmin.topics().deletePartitionedTopic(topic); // may fail if partitions linger\n// after\nawait().atMost(30, SECONDS).until(() -> admin.topics().getPartitionedTopicMetadata(topic).partitions > 0 ? admin.topics().getList(namespace).stream().noneMatch(t -> t.startsWith(topic + PersistentTopicInternalTopics.PARTITIONED_TOPIC_SUFFIX) && !t.equals(topic)) : true);\nadmin.topics().deletePartitionedTopic(topic);","handlingStrategy":"retry","validationCode":"boolean allPartitionsGone(String partitionedTopic, int partitions) throws PulsarAdminException {\n    for (int i = 0; i < partitions; i++) {\n        try {\n            admin.topics().getStats(partitionedTopic + \"-partition-\" + i);\n            return false; // partition still exists\n        } catch (PulsarAdminException.NotFoundException e) { /* gone */ }\n    }\n    return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n    admin.topics().deletePartitionedTopic(topic);\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage().contains(\"Another partition exists\")) {\n        // wait for partitions to disappear, then retry\n        Thread.sleep(5000);\n        admin.topics().deletePartitionedTopic(topic);\n    } else throw e;\n}","preventionTips":["Stop producers/consumers before deleting partitioned topics","Delete partitions first and verify they are gone before removing metadata","Be aware of broker topic-list caching delays after partition deletion"],"tags":["pulsar","broker","topic-deletion","partitioned-topic","unsupported-operation"],"backgroundTag":"partitioned-topic-delete-conflict","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}