apache/pulsar · warning · RestException

Proxy doesn't have logging level 2

Error message

Proxy doesn't have logging level 2

What it means

The proxy REST /topics stats endpoint only captures topic-level stats when the proxy's dynamic log level is >= 2, because topic stats collection piggybacks on verbose logging machinery. ProxyStats.topics enforces this precondition with HTTP 412 when proxyLogLevel is absent or below 2.

Solutions

  1. Raise the proxy log level first: POST /admin/v2/proxy-stats/logging/2 (requires superuser role)
  2. Set proxyLogLevel=2 in the proxy configuration file so it survives restarts
  3. If only aggregate metrics are needed, use the /metrics endpoint instead of topic-level stats
  4. Ensure the client authenticating to the REST endpoint has superuser permissions so the request reaches the log-level check

Example fix

// before
proxyLogLevel=1

// after
proxyLogLevel=2
Defensive patterns

Strategy: validation

Validate before calling

Integer logLevel = proxyConfig.getProxyLogLevel().orElse(0);
if (logLevel < 2) {
    // raise first, then query
    admin.postProxyLogLevel(2);
}
Map<String, TopicStats> stats = admin.getTopics();

Type guard

boolean topicStatsEnabled(ProxyConfiguration cfg) {
    return cfg.getProxyLogLevel().map(l -> l >= 2).orElse(false);
}

Try / catch

try {
    return proxyStats.topics();
} catch (RestException e) {
    if (e.getResponseStatus() == 412) {
        proxyStats.updateProxyLogLevel(2);
        return proxyStats.topics();
    }
    throw e;
}

Prevention

When it happens

Trigger: GET /admin/v2/proxy-stats/topics (via ProxyStats.topics) while getConfiguration().getProxyLogLevel() is unset or < 2 — e.g. before anyone called POST /logging/{logLevel} or the config file has no proxyLogLevel entry.

Common situations: Monitoring/scraping tools querying topic stats on a fresh proxy whose proxyLogLevel defaults below 2; operators forgetting to raise the log level after restart; automated dashboards hitting the endpoint on a proxy configured with proxyLogLevel=1.

Related errors


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

Appendix: source

Thrown at pulsar-proxy/src/main/java/org/apache/pulsar/proxy/stats/ProxyStats.java:105

            stats.add(new ConnectionStats(requestRate, byteRate, inboundChannel, outboundChannel));
        });
        return stats;
    }

    @GET
    @Path("/topics")
    @Operation(summary = "Proxy topic stats api")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "Proxy topic stats api",
                    content = @Content(schema = @Schema(type = "object"),
                            additionalPropertiesSchema = @Schema(implementation = Map.class))),
            @ApiResponse(responseCode = "412", description = "Proxy logging should be > 2 to capture topic stats"),
            @ApiResponse(responseCode = "503", description = "Proxy service is not initialized") })
    public Map<String, TopicStats> topics() {
        throwIfNotSuperUser("topics");
        Optional<Integer> logLevel = proxyService().getConfiguration().getProxyLogLevel();
        if (!logLevel.isPresent() || logLevel.get() < 2) {
            throw new RestException(Status.PRECONDITION_FAILED, "Proxy doesn't have logging level 2");
        }
        return proxyService().getTopicStats();
    }

    @POST
    @Path("/logging/{logLevel}")
    @Operation(hidden = true, summary = "Change proxy logging level dynamically",
            description = "It only changes the log level in memory; change it in the config file to persist the change")
    @ApiResponses(value = { @ApiResponse(responseCode = "412", description = "Proxy log level can be [0-2]"), })
    public void updateProxyLogLevel(@PathParam("logLevel") int logLevel) {
        throwIfNotSuperUser("updateProxyLogLevel");
        if (logLevel < 0 || logLevel > 2) {
            throw new RestException(Status.PRECONDITION_FAILED, "Proxy log level can be only [0-2]");
        }
        proxyService().setProxyLogLevel(logLevel);
    }

    @GET

View on GitHub (pinned to 820761864e)