apache/pulsar · error · IllegalArgumentException

recoverThreshold must be larger than 0

Error message

recoverThreshold must be larger than 0

What it means

The Builder.recoverThreshold(int) setter validates that the recover threshold (consecutive successful probes before switching back to the primary cluster) is at least 1. A value below 1 would make fail-back logic nonsensical, so IllegalArgumentException is thrown.

Source

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

        return new Builder();
    }

    public static class Builder {

        private SameAuthParamsLookupAutoClusterFailover
                sameAuthParamsLookupAutoClusterFailover = new SameAuthParamsLookupAutoClusterFailover();

        public Builder failoverThreshold(int failoverThreshold) {
            if (failoverThreshold < 1) {
                throw new IllegalArgumentException("failoverThreshold must be larger than 0");
            }
            sameAuthParamsLookupAutoClusterFailover.failoverThreshold = failoverThreshold;
            return this;
        }

        public Builder recoverThreshold(int recoverThreshold) {
            if (recoverThreshold < 1) {
                throw new IllegalArgumentException("recoverThreshold must be larger than 0");
            }
            sameAuthParamsLookupAutoClusterFailover.recoverThreshold = recoverThreshold;
            return this;
        }

        public Builder checkHealthyIntervalMs(int checkHealthyIntervalMs) {
            if (checkHealthyIntervalMs < 1) {
                throw new IllegalArgumentException("checkHealthyIntervalMs must be larger than 0");
            }
            sameAuthParamsLookupAutoClusterFailover.checkHealthyIntervalMs = checkHealthyIntervalMs;
            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;

View on GitHub (pinned to 820761864e)

Solutions

  1. Pass a positive integer (>= 1) to recoverThreshold.
  2. Apply a documented default when the configuration value is absent or zero before building.
  3. Validate all failover-related integers together in one config-validation pass.

Example fix

// before
builder.recoverThreshold(props.get("recoverThreshold", 0));

// after
builder.recoverThreshold(Math.max(1, props.get("recoverThreshold", 3)));
Defensive patterns

Strategy: validation

Validate before calling

int recoverThreshold = cfg.getRecoverThreshold();
if (recoverThreshold < 1) {
    recoverThreshold = 3;
}

Try / catch

try {
    builder.recoverThreshold(t);
} catch (IllegalArgumentException e) {
    log.warn("Invalid recoverThreshold, using default 3", e);
    builder.recoverThreshold(3);
}

Prevention

When it happens

Trigger: Calling recoverThreshold(0) or a negative value on the SameAuthParamsLookupAutoClusterFailover Builder, often from an unset config field defaulting to 0.

Common situations: Missing config entry for the recover threshold; copy-pasted builder code where the wrong variable (e.g. an uninitialized counter) is passed.

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/e2640cfc49230197. Report an issue: GitHub.