apache/pulsar · warning · RestException

Topic does not exist

Error message

Topic does not exist

What it means

internalGetStats validates access then looks up the in-memory ProxyTopicStat for the given topic name. If no stats object exists the topic has no active proxy handlers, so it returns HTTP 404 with 'Topic does not exist' via RestException. This is a lookup miss on the proxy's live handler registry, not a broker-side topic check.

Source

Thrown at pulsar-websocket/src/main/java/org/apache/pulsar/websocket/admin/WebSocketProxyStatsBase.java:51

@CustomLog
public class WebSocketProxyStatsBase extends WebSocketWebResource {

    protected Collection<Metrics> internalGetMetrics() throws Exception {
        // Ensure super user access only
        validateSuperUserAccess();
        try {
            return service().getProxyStats().getMetrics();
        } catch (Exception e) {
            log.error().attr("clientAppId", clientAppId()).exception(e).log("Failed to generate metrics");
            throw new RestException(e);
        }
    }

    protected ProxyTopicStat internalGetStats(TopicName topicName) {
        validateUserAccess(topicName);
        ProxyTopicStat stats = getStat(topicName);
        if (stats == null) {
            throw new RestException(Status.NOT_FOUND, "Topic does not exist");
        }
        return stats;
    }

    protected Map<String, ProxyTopicStat> internalGetProxyStats() {
        validateSuperUserAccess();
        return getStat();
    }

    private ProxyTopicStat getStat(TopicName topicName) {
        String topicNameStr = topicName.toString();
        if (!service().getProducers().containsKey(topicNameStr) && !service().getConsumers().containsKey(topicNameStr)
                && !service().getReaders().containsKey(topicNameStr)) {
            log.warn().attr("exist", topicNameStr).log("topic doesn't exist");
            throw new RestException(Status.NOT_FOUND, "Topic does not exist");
        }
        ProxyTopicStat topicStat = new ProxyTopicStat();
        if (service().getProducers().containsKey(topicNameStr)) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Open a WebSocket producer/consumer/reader on the topic before requesting its proxy stats
  2. Verify the exact topic name (tenant/namespace/topic) and that you are querying the proxy instance that holds the connection
  3. Handle HTTP 404 from the stats endpoint gracefully — treat it as 'no active proxy sessions' rather than a hard failure
  4. Aggregate stats across proxy instances via broker-level topic stats if the connection may live on another node
Defensive patterns

Strategy: try-catch

Validate before calling

// client-side: only request stats when a connection is known active
if (!activeConnections.containsKey(topicName)) { throw new IllegalStateException("no active proxy session for " + topicName); }

Try / catch

Response r = target.path(topicName + "/stats").get(); if (r.getStatus() == 404) { return Optional.empty(); } return Optional.of(r.readEntity(ProxyTopicStat.class));

Prevention

When it happens

Trigger: GET /admin/v2/websocket/.../stats/<topic> where the topic has no currently open WebSocket producers, consumers, or readers in this proxy instance (getStat(topicName) returned null).

Common situations: Querying stats after the client disconnected; querying the wrong topic name/tenant/namespace; hitting a different proxy instance than the one holding the connection (no shared stats store); typo in the topic path.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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