apache/pulsar · error · IllegalStateException

ServiceUrlProvider has already been initialized

Error message

ServiceUrlProvider has already been initialized

What it means

Single-initialization guard in AutoClusterFailover.initialize: the ServiceUrlProvider has already been initialized (typically the PulsarClient called initialize twice, or a new client reused the provider), so the second call is rejected to avoid re-registering the state updater and resetting failover state.

Source

Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/AutoClusterFailover.java:99

        this.secondaryAuthentications = builder.secondaryAuthentications;
        this.secondaryTlsTrustCertsFilePaths = builder.secondaryTlsTrustCertsFilePaths;
        this.secondaryTlsTrustStorePaths = builder.secondaryTlsTrustStorePaths;
        this.secondaryTlsTrustStorePasswords = builder.secondaryTlsTrustStorePasswords;
        this.failoverDelayNs = builder.failoverDelayNs;
        this.switchBackDelayNs = builder.switchBackDelayNs;
        this.currentPulsarServiceUrl = builder.primary;
        this.recoverTimestamp = -1;
        this.failedTimestamp = -1;
        this.intervalMs = builder.checkIntervalMs;
        this.resolver = new PulsarServiceNameResolver();
        this.executor = Executors.newSingleThreadScheduledExecutor(
                new ExecutorProvider.ExtendedThreadFactory("pulsar-service-provider"));
    }

    @Override
    public synchronized void initialize(PulsarClient client) {
        if (this.pulsarClient != null) {
            throw new IllegalStateException("ServiceUrlProvider has already been initialized");
        }
        this.pulsarClient = (PulsarClientImpl) client;
        this.addressResolver = pulsarClient.getAddressResolver();
        ClientConfigurationData config = pulsarClient.getConfiguration();
        if (config != null) {
            this.primaryAuthentication = config.getAuthentication();
            this.primaryTlsTrustCertsFilePath = config.getTlsTrustCertsFilePath();
            this.primaryTlsTrustStorePath = config.getTlsTrustStorePath();
            this.primaryTlsTrustStorePassword = config.getTlsTrustStorePassword();
        }

        // start to probe primary cluster active or not
        this.executor.scheduleAtFixedRate(catchingAndLoggingThrowables(() -> {
            if (currentPulsarServiceUrl.equals(primary)) {
                // current service url is primary, probe whether it is down
                probeAndUpdateServiceUrl(secondary, secondaryAuthentications, secondaryTlsTrustCertsFilePaths,
                        secondaryTlsTrustStorePaths, secondaryTlsTrustStorePasswords);
            } else {

View on GitHub (pinned to 820761864e)

Solutions

  1. Initialize the failover client only once per builder
  2. Create a new instance instead of re-initializing
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/AutoClusterFailover.java:99 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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