apache/pulsar · error · IllegalArgumentException

earlyTokenRefreshPercent must be greater than 0.

Error message

earlyTokenRefreshPercent must be greater than 0.

What it means

AuthenticationFactoryOAuth2.ClientCredentialsBuilder.earlyTokenRefreshPercent() validates its argument before storing it. The value must be a positive fraction in (0, 1) to enable early refresh, or >= 1 to disable it; a value <= 0 is meaningless and throws this IllegalArgumentException immediately.

Source

Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/oauth2/AuthenticationFactoryOAuth2.java:282

            return this;
        }

        /**
         * The fraction of the token's {@code expires_in} time at which the client starts attempting
         * a background refresh. Must be greater than 0. Values &ge; 1 disable early refresh (the default).
         *
         * <p>For example, {@code 0.8} means the client will attempt to refresh after 80% of the
         * token lifetime has elapsed, leaving a 20% buffer to tolerate a temporary OAuth server
         * outage while the existing token is still valid. During an outage the client keeps retrying
         * in the background with exponential backoff, continuing to serve requests with the current
         * token until it actually expires.
         *
         * @param earlyTokenRefreshPercent fractional value in (0, 1) to enable, or &ge; 1 to disable
         * @return the builder
         */
        public ClientCredentialsBuilder earlyTokenRefreshPercent(double earlyTokenRefreshPercent) {
            if (earlyTokenRefreshPercent <= 0) {
                throw new IllegalArgumentException("earlyTokenRefreshPercent must be greater than 0.");
            }
            this.earlyTokenRefreshPercent = earlyTokenRefreshPercent;
            return this;
        }

        /**
         * Optional scheduler for background token refresh tasks. If not set and early refresh is
         * enabled, a shared internal daemon-thread scheduler is used automatically.
         * {@link AuthenticationOAuth2} will never shut down a caller-supplied scheduler.
         *
         * @param scheduler the scheduler to use for background token refresh
         * @return the builder
         */
        public ClientCredentialsBuilder scheduler(ScheduledExecutorService scheduler) {
            this.scheduler = scheduler;
            return this;
        }

View on GitHub (pinned to 820761864e)

Solutions

  1. Pass a value in (0, 1) to enable, e.g. 0.2 for 20% of token lifetime.
  2. To disable early refresh pass a value >= 1 (e.g. 1 or 100), not 0.
  3. Guard config-sourced values: default to 1 (disabled) when the config key is missing or <= 0.

Example fix

// before
builder.earlyTokenRefreshPercent(cfg.getEarlyRefresh()); // 0 when unset -> throws
// after
double pct = cfg.getEarlyRefresh() > 0 ? cfg.getEarlyRefresh() : 1; // >=1 disables
builder.earlyTokenRefreshPercent(pct);
Defensive patterns

Strategy: validation

Validate before calling

double v = config.earlyTokenRefreshPercent();
if (!(v > 0)) { // rejects 0, negative, NaN
    throw new IllegalArgumentException("earlyTokenRefreshPercent must be > 0 (use >= 1 to disable)");
}
builder.earlyTokenRefreshPercent(v);

Try / catch

try {
    builder.earlyTokenRefreshPercent(pct);
} catch (IllegalArgumentException e) {
    log.warn("Invalid earlyTokenRefreshPercent {}, falling back to disabled (1.0)", pct);
    builder.earlyTokenRefreshPercent(1.0);
}

Prevention

When it happens

Trigger: Calling .earlyTokenRefreshPercent(0), .earlyTokenRefreshPercent(-0.1), or any other value <= 0 while building the OAuth2 authentication via the builder.

Common situations: Loading the refresh percentage from config/environment where an unset value defaults to 0; a config file intended to 'disable' early refresh uses 0 instead of >= 1 (e.g. 1 or 100); sign errors when converting a percentage.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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