Hi Rajan, existing deployment using v1 era topics already had 8 years to start a migration. I don't see how waiting more time will help here.
These deployments can keep staying on the 4.0.x LTS version which is still going to be maintained for significant time. I'm not against a migration mechanism, though that would require significant effort. I'm happy to help out whoever wants to work on that. Right now, I think the complexity throughout the code base required to support v1/v2 greatly overweights the benefits and it severely hinders the ability to further evolve and push Pulsar forward. Thanks, Matteo -- Matteo Merli <[email protected]> On Fri, Feb 27, 2026 at 10:31 AM Rajan Dhabalia <[email protected]> wrote: > > Hi Matteo, > > I completely understand your concern and the motivation behind this. > > However, there are still large scale Pulsar deployments with a significant > number of V1 topic names. Removing V1 topic support would effectively > require those systems to stop using Pulsar, which does not seem like the > right approach. > > We should introduce a migration mechanism to move V1 topics to the newer > version so legacy systems have a clear transition path. I would not > recommend removing V1 topic support without first defining and agreeing on > a migration strategy. > > Thanks, > Rajan > > On Fri, Feb 27, 2026 at 9:50 AM Matteo Merli <[email protected]> wrote: > > > https://github.com/apache/pulsar/pull/25275 > > > > > > # PIP-457: Remove support for V1 topic names and V1 Admin API > > > > ## Background knowledge > > > > Apache Pulsar historically supported two topic naming formats: > > > > - **V1 format**: `persistent://tenant/cluster/namespace/topic` — > > includes the cluster name in the topic path > > - **V2 format**: `persistent://tenant/namespace/topic` — omits the > > cluster name, making all namespaces implicitly "global" > > > > The V1 format was the original naming convention from Pulsar's early > > days. PIP-10 introduced V2 topic names in Pulsar 2.0 (released June > > 2018) by removing the cluster component, and PIP-11 further simplified > > naming with short topic names defaulting to > > `persistent://public/default/`. V1 topic names have been deprecated > > since Pulsar 2.0 — nearly 8 years ago at the time of this proposal. > > > > The V1 naming format also implied a separate set of Admin REST API > > endpoints, Lookup endpoints, and WebSocket paths that include > > `{property}/{cluster}/{namespace}` in their URL structure, as opposed > > to the V2 paths using `{tenant}/{namespace}`. > > > > These V1 APIs have been deprecated and hidden from the API > > documentation for many years. The V2 format has been the recommended > > and default format since Pulsar 2.0. > > > > ## Motivation > > > > The continued presence of V1 topic name support imposes several costs > > on the project: > > > > 1. **Maintenance burden**: Every Admin API operation must be > > duplicated across V1 and V2 endpoint classes (`v1.PersistentTopics`, > > `v1.NonPersistentTopics`, `v1.Namespaces`, `v1.TopicLookup` alongside > > their V2 counterparts). Bug fixes and new features touching admin APIs > > must account for both code paths. > > > > 2. **Increased attack surface**: The V1 endpoints are hidden from > > documentation but still active and routable, creating undocumented API > > surface area that must be secured, tested, and maintained. > > > > 3. **Code complexity in TopicName parsing**: The `TopicName` class > > must handle both 3-part (V2) and 4-part (V1) name parsing, and the > > `isV2()` check propagates throughout the broker, lookup, and client > > code. > > > > 4. **WebSocket handler complexity**: WebSocket paths must support both > > `/ws/producer/persistent/{property}/{cluster}/{namespace}/{topic}` > > (V1) and `/ws/v2/producer/persistent/{tenant}/{namespace}/{topic}` > > (V2). > > > > 5. **Confusion for new contributors and operators**: The existence of > > two naming schemes and two sets of admin APIs creates unnecessary > > confusion and cognitive overhead. > > > > 6. **Test matrix expansion**: V1 paths must be covered by integration > > and unit tests, expanding the test matrix without providing value to > > modern deployments. > > > > V1 topics have been deprecated since Pulsar 2.0, released in June > > 2018. With nearly 8 years having passed and the project now on the 4.x > > release line, it is time to complete this deprecation and remove V1 > > support entirely. > > > > ## Goals > > > > ### In Scope > > > > - Remove all V1 Admin REST API endpoint classes and their registrations: > > - `org.apache.pulsar.broker.admin.v1.PersistentTopics` > > - `org.apache.pulsar.broker.admin.v1.NonPersistentTopics` > > - `org.apache.pulsar.broker.admin.v1.Namespaces` > > - `org.apache.pulsar.broker.admin.v1.Clusters` (if present) > > - Remove V1 topic lookup endpoint: > > - `org.apache.pulsar.broker.lookup.v1.TopicLookup` > > - Remove V1 WebSocket handler paths > > - Remove V1 (4-part) topic name parsing from `TopicName` and related > > classes > > - Remove `isV2()` method and all conditional branching based on V1 vs > > V2 topic format > > - Remove `LOOKUP_PATH_V1` constant and related redirect logic > > - Remove or update all tests that exercise V1 code paths > > - Update CLI tools that may still reference V1 format > > - Log a clear error message if a client attempts to use a V1-style > > topic name, to aid migration > > > > ### Out of Scope > > > > - Removal of the V2 Admin API in favor of V4 (that would be a separate PIP) > > - Changes to the binary protocol wire format > > - Metadata store migration of existing V1 topic metadata (this PIP > > covers code removal; data migration would be addressed separately if > > needed) > > > > ## High Level Design > > > > The removal will be executed in a single coordinated change: > > > > 1. **Admin API**: Delete the `v1` package under > > `pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v1/` and > > remove the registration of V1 REST resources from the broker's web > > server initialization. > > > > 2. **Lookup**: Delete > > > > `pulsar-broker/src/main/java/org/apache/pulsar/broker/lookup/v1/TopicLookup.java` > > and remove its registration. > > > > 3. **TopicName parsing**: Simplify `TopicName` to only accept the > > 3-part V2 format (`domain://tenant/namespace/localName`). If a 4-part > > name is provided, throw a clear `IllegalArgumentException` with a > > message explaining V1 names are no longer supported and how to > > convert. > > > > 4. **WebSocket**: Remove V1 URI parsing paths from > > `AbstractWebSocketHandler` and related classes. > > > > 5. **Tests**: Remove or convert all V1-specific test cases. Tests that > > coincidentally use V1 names should be updated to V2 format. > > > > ## Detailed Design > > > > ### Admin API Removal > > > > The following classes will be deleted: > > - > > `pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v1/PersistentTopics.java` > > - > > `pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v1/NonPersistentTopics.java` > > - > > `pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v1/Namespaces.java` > > > > Their registration in the broker's Jersey/JAX-RS application > > configuration will be removed. > > > > ### TopicName Simplification > > > > In `pulsar-common`, the `TopicName` class will be modified: > > > > ```java > > // Before: accepts both V1 (4 parts) and V2 (3 parts) > > // After: only accepts V2 (3 parts) > > private TopicName(String completeTopicName) { > > // ... parse domain:// > > String[] parts = rest.split("/", 3); // tenant/namespace/localName > > if (parts.length != 3) { > > throw new IllegalArgumentException( > > "Invalid topic name '" + completeTopicName + "'. " > > + "Expected format: 'persistent://tenant/namespace/topic'. " > > + "V1 topic names (with cluster component) are no longer > > supported. " > > + "Please use the V2 format without the cluster name."); > > } > > this.tenant = parts[0]; > > this.namespace = parts[1]; > > this.localName = parts[2]; > > // cluster field removed entirely > > } > > ``` > > > > The `isV2()` method and `cluster` field will be removed from > > `TopicName`. All call sites that branch on `isV2()` will be > > simplified. > > > > The `NamespaceName` class will similarly be simplified to remove V1 > > support. > > > > ### Lookup Simplification > > > > The `LOOKUP_PATH_V1` constant and any conditional logic choosing > > between V1/V2 redirect paths will be removed. Lookups will only use V2 > > paths. > > > > ### WebSocket Simplification > > > > The `getTopic()` method in WebSocket handler classes will be > > simplified to only parse V2-style URIs (`/ws/v2/...`). > > > > ## Public-facing Changes > > > > ### REST API > > > > The following REST API paths will be **removed**: > > > > **Persistent Topics (V1)**: > > - `GET /admin/persistent/{property}/{cluster}/{namespace}` — list topics > > - `GET/PUT/DELETE > > /admin/persistent/{property}/{cluster}/{namespace}/{topic}/...` — all > > topic operations > > - `GET/PUT/DELETE > > /admin/persistent/{property}/{cluster}/{namespace}/partitioned` — > > partitioned topic operations > > > > **Non-Persistent Topics (V1)**: > > - `GET /admin/non-persistent/{property}/{cluster}/{namespace}` — list > > topics > > - `GET/PUT/DELETE > > /admin/non-persistent/{property}/{cluster}/{namespace}/{topic}/...` — > > all topic operations > > > > **Namespaces (V1)**: > > - `GET/PUT/DELETE /admin/namespaces/{property}/{cluster}/{namespace}` > > — all namespace operations > > > > **Lookup (V1)**: > > - `GET > > /lookup/v2/destination/{topic-domain}/{property}/{cluster}/{namespace}/{topic}` > > — topic lookup > > > > ### Binary Protocol > > > > No changes to the binary protocol. > > > > ### Configuration > > > > No new configuration. The broker configuration key `allowV1Topics` may > > be considered for a transitional release but is **not** proposed here > > — the removal is clean and complete. > > > > ### CLI > > > > `pulsar-admin` and `pulsar-client` CLI tools will only accept V2 topic > > names. Passing a V1 topic name will produce a clear error message with > > migration guidance. > > > > ### Metrics > > > > No metrics changes. > > > > ## Monitoring > > > > Operators should monitor for client errors after the upgrade. Clients > > attempting to use V1 topic names will receive clear error responses > > (HTTP 404 for V1 admin paths, or client-side > > `IllegalArgumentException` for V1 topic names). > > > > ## Security Considerations > > > > This change reduces the API attack surface by removing undocumented > > but active REST endpoints. No new security considerations are > > introduced. > > > > ## Backward & Forward Compatibility > > > > ### Upgrade > > > > This is a **breaking change** for any deployment still using V1 topic > > names or V1 Admin API paths. > > > > Before upgrading to the version containing this change, operators must: > > 1. Ensure all topic names in use follow the V2 format > > (`persistent://tenant/namespace/topic`) > > 2. Ensure all Admin API clients use V2 endpoints (`/admin/v2/...`) > > 3. Ensure all WebSocket clients use V2 paths (`/ws/v2/...`) > > > > The V1 format has been deprecated since Pulsar 2.0, released in June > > 2018 — nearly 8 years ago. Any deployment that has been maintained on > > a supported Pulsar version should already be using V2 format > > exclusively. > > > > ### Downgrade / Rollback > > > > Rolling back to a prior version that supports V1 topic names will work > > without issues, as no data format changes are involved. > > > > ### Geo-Replication > > > > No impact. Geo-replication already uses V2 topic names. The cluster > > component in V1 topic names was originally related to replication > > configuration but has been decoupled since V2 was introduced. > > > > ## General Notes > > > > ### Related PIPs > > - PIP-10: Remove cluster from topic name (introduced V2 naming) > > - PIP-11: Short topic name (further simplified topic naming) > > - PIP-48: Proposed V4 admin API (future direction for admin APIs) > > > > ### Migration Guide > > > > For any users who may still be using V1 topic names, the migration is > > straightforward: > > > > | V1 Format | V2 Format | > > |---|---| > > | `persistent://my-tenant/my-cluster/my-namespace/my-topic` | > > `persistent://my-tenant/my-namespace/my-topic` | > > | `/admin/persistent/my-tenant/my-cluster/my-namespace` | > > `/admin/v2/persistent/my-tenant/my-namespace` | > > | `/ws/producer/persistent/my-tenant/my-cluster/my-ns/my-topic` | > > `/ws/v2/producer/persistent/my-tenant/my-ns/my-topic` | > > > > Simply remove the cluster component from the topic name path. > > > > > > > > > > > > -- > > Matteo Merli > > <[email protected]> > >
