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]>
>

Reply via email to