apache/pulsar · error · IllegalArgumentException

pulsarServiceUrlArray can not be empty

Error message

pulsarServiceUrlArray can not be empty

What it means

Builder.pulsarServiceUrlArray(String[]) requires a non-null, non-empty array of Pulsar service URLs because the failover provider needs at least one cluster to fail over between. A null or zero-length array triggers IllegalArgumentException.

Source

Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/SameAuthParamsLookupAutoClusterFailover.java:356

            return this;
        }

        public Builder testTopic(String testTopic) {
            if (StringUtils.isBlank(testTopic) && TopicName.get(testTopic) != null) {
                throw new IllegalArgumentException("testTopic can not be blank");
            }
            sameAuthParamsLookupAutoClusterFailover.testTopic = testTopic;
            return this;
        }

        public Builder markTopicNotFoundAsAvailable(boolean markTopicNotFoundAsAvailable) {
            sameAuthParamsLookupAutoClusterFailover.markTopicNotFoundAsAvailable = markTopicNotFoundAsAvailable;
            return this;
        }

        public Builder pulsarServiceUrlArray(String[] pulsarServiceUrlArray) {
            if (pulsarServiceUrlArray == null || pulsarServiceUrlArray.length == 0) {
                throw new IllegalArgumentException("pulsarServiceUrlArray can not be empty");
            }
            sameAuthParamsLookupAutoClusterFailover.pulsarServiceUrlArray = pulsarServiceUrlArray;
            int pulsarServiceLen = pulsarServiceUrlArray.length;
            HashSet<String> uniqueChecker = new HashSet<>();
            for (int i = 0; i < pulsarServiceLen; i++) {
                String pulsarService = pulsarServiceUrlArray[i];
                if (StringUtils.isBlank(pulsarService)) {
                    throw new IllegalArgumentException("pulsarServiceUrlArray contains a blank value at index " + i);
                }
                if (pulsarService.startsWith("http") || pulsarService.startsWith("HTTP")) {
                    throw new IllegalArgumentException("SameAuthParamsLookupAutoClusterFailover does not support HTTP"
                            + " protocol pulsar service url so far.");
                }
                if (!uniqueChecker.add(pulsarService)) {
                    throw new IllegalArgumentException("pulsarServiceUrlArray contains duplicated value "
                            + pulsarServiceUrlArray[i]);
                }
            }

View on GitHub (pinned to 820761864e)

Solutions

  1. Pass an array with at least one valid pulsar+ssl:// (or pulsar://) service URL.
  2. In config loading, check the cluster list size before building and surface a clear configuration error.
  3. Use the standard single-cluster client setup if you only have one cluster — this failover provider is not needed.

Example fix

// before
String[] urls = cfg.get("clusters", "").split(",");
builder.pulsarServiceUrlArray(urls); // [""] or empty

// after
String[] urls = Arrays.stream(cfg.get("clusters", "").split(","))
    .map(String::trim).filter(s -> !s.isEmpty()).toArray(String[]::new);
if (urls.length == 0) throw new IllegalArgumentException("At least one cluster URL is required");
builder.pulsarServiceUrlArray(urls);
Defensive patterns

Strategy: validation

Validate before calling

String[] urls = parseUrls(cfg.getClusters());
if (urls == null || urls.length == 0) {
    throw new IllegalArgumentException("At least one cluster service URL is required");
}

Try / catch

try {
    builder.pulsarServiceUrlArray(urls);
} catch (IllegalArgumentException e) {
    log.error("Cluster URL list is empty; failover provider cannot start", e);
    throw new ConfigurationException("clusters must list at least one service URL", e);
}

Prevention

When it happens

Trigger: Calling pulsarServiceUrlArray(null) or pulsarServiceUrlArray(new String[0]) on the SameAuthParamsLookupAutoClusterFailover Builder, e.g. when a comma-separated config list split to an empty array.

Common situations: Config property 'clusters=' empty or missing; splitting an empty string with String.split(",") and passing the result; programmatic construction before the cluster list is loaded from a registry.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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