apache/pulsar · critical · PulsarServerException

Failed to retrieve Cluster data due to empty ConfigurationSt

Error message

Failed to retrieve Cluster data due to empty ConfigurationStoreServers

What it means

retrieveClusterData() looks up the proxy's cluster data via pulsarResources, but when pulsarResources is null (ConfigurationStoreServers empty) it throws PulsarServerException immediately. Called from getPulsarClient, this prevents the proxy from constructing the client that WebSocket handlers need.

Source

Thrown at pulsar-websocket/src/main/java/org/apache/pulsar/websocket/WebSocketService.java:301

            return ClusterData.builder()
                    .serviceUrl(config.getServiceUrl())
                    .serviceUrlTls(config.getServiceUrlTls())
                    .brokerServiceUrl(config.getBrokerServiceUrl())
                    .brokerServiceUrlTls(config.getBrokerServiceUrlTls())
                    .build();
        } else if (isNotBlank(config.getServiceUrl()) || isNotBlank(config.getServiceUrlTls())) {
            return ClusterData.builder()
                    .serviceUrl(config.getServiceUrl())
                    .serviceUrlTls(config.getServiceUrlTls())
                    .build();
        } else {
            return null;
        }
    }

    private ClusterData retrieveClusterData() throws PulsarServerException {
        if (pulsarResources == null) {
            throw new PulsarServerException(
                "Failed to retrieve Cluster data due to empty ConfigurationStoreServers");
        }
        try {
            return localCluster = pulsarResources.getClusterResources().getCluster(config.getClusterName())
                    .orElseThrow(() -> new NotFoundException("Cluster " + config.getClusterName()));
        } catch (Exception e) {
            throw new PulsarServerException(e);
        }
    }

    public ProxyStats getProxyStats() {
        return proxyStats;
    }

    public ScheduledExecutorService getExecutor() {
        return executor;
    }

View on GitHub (pinned to 820761864e)

Solutions

  1. Configure configurationStoreServers so pulsarResources is initialized at startup
  2. If a serviceUrl/client is provided directly, ensure that path is used and the proxy doesn't need cluster lookup (check config.isConfigurationStoreServiceAvailable()/equivalent)
  3. Restart and confirm startup logs show PulsarResources created successfully
  4. Add a startup check/fail-fast so the misconfiguration is caught before client traffic arrives

Example fix

// before
# websocket.conf
clusterName=my-cluster
# no configurationStoreServers
// after
clusterName=my-cluster
configurationStoreServers=zk1:2181
Defensive patterns

Strategy: retry

Validate before calling

if (service.getPulsarResources() == null) { throw new IllegalStateException("Proxy not fully initialized: configurationStoreServers missing; client connections will fail"); }

Type guard

boolean proxyReady(WebSocketService s) { return s != null && s.getPulsarResources() != null && s.getClient() != null; }

Try / catch

CompletableFuture<PulsarClient> f = service.getPulsarClient(); f.exceptionally(e -> { if (e.getCause() instanceof PulsarServerException) { restartWithFixedConfig(); } return null; });

Prevention

When it happens

Trigger: A producer/consumer/reader connects and getPulsarClient -> retrieveClusterData runs while pulsarResources is null because configurationStoreServers was not configured.

Common situations: Same root cause as startup auth failure but surfaces later at first connection: proxy started with empty configurationStoreServers; metadata store removed from config during migration; proxy running in a reduced config that skips resource initialization.

Related errors


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