apache/pulsar · error · IllegalArgumentException

EarlyTokenRefreshPercent must be greater than 0.

Error message

EarlyTokenRefreshPercent must be greater than 0.

What it means

The private AuthenticationOAuth2 constructor validates earlyTokenRefreshPercent: it must be > 0 (values in (0,1) enable early refresh; values >= 1 disable it). The public builder already enforces this, but any code path reaching the constructor with <= 0 (e.g. reflectively or via configure-parsed parameters) throws this IllegalArgumentException.

Source

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

    AuthenticationOAuth2(Flow flow,
                         Clock clock,
                         double earlyTokenRefreshPercent,
                         ScheduledExecutorService scheduler) {
        this(clock, earlyTokenRefreshPercent, scheduler);
        this.flow = flow;
    }

    /**
     * @param clock - clock to use when determining token expiration.
     * @param earlyTokenRefreshPercent - see javadoc for {@link AuthenticationOAuth2}. Must be greater than 0.
     * @param scheduler - The scheduler to use for background token refreshes. If {@code null} and
     *                  {@link #earlyTokenRefreshPercent} is less than 1, the shared internal daemon-thread
     *                  scheduler is used. If the caller supplies a scheduler, this class will not shut it down.
     */
    private AuthenticationOAuth2(Clock clock, double earlyTokenRefreshPercent, ScheduledExecutorService scheduler) {
        if (earlyTokenRefreshPercent <= 0) {
            throw new IllegalArgumentException("EarlyTokenRefreshPercent must be greater than 0.");
        }
        this.earlyTokenRefreshPercent = earlyTokenRefreshPercent;
        this.clock = clock;
        if (scheduler == null && earlyTokenRefreshPercent < 1) {
            this.scheduler = INTERNAL_SCHEDULER;
        } else {
            this.scheduler = scheduler;
        }
    }

    @Override
    public String getAuthMethodName() {
        return AUTH_METHOD_NAME;
    }

    @Override
    public void configure(String encodedAuthParamString) {
        Map<String, String> params = parseAuthParameters(encodedAuthParamString);

View on GitHub (pinned to 820761864e)

Solutions

  1. Pass a value in (0,1) to enable early refresh or >= 1 to disable; never 0 or negative.
  2. Prefer the official builder (AuthenticationFactoryOAuth2) which validates earlier with a clearer message.
  3. Sanitize config values: treat missing/0 as 1 (disabled).

Example fix

// before
new AuthenticationOAuth2(clock, 0.0, null); // throws
// after
new AuthenticationOAuth2(clock, 1.0, null); // >=1 disables early refresh
Defensive patterns

Strategy: validation

Validate before calling

if (!(pct > 0)) {
    pct = 1.0; // disable early refresh
}
Authentication auth = AuthenticationFactoryOAuth2
    .clientCredentials(issuerUrl, clientId, clientSecret)
    .earlyTokenRefreshPercent(pct)
    .build();

Try / catch

try {
    return buildAuth(pct);
} catch (IllegalArgumentException e) {
    throw new ConfigurationException("earlyTokenRefreshPercent must be > 0; use >= 1 to disable", e);
}

Prevention

When it happens

Trigger: Constructing AuthenticationOAuth2 with earlyTokenRefreshPercent <= 0 through an internal/factory path, or a flow builder path that bypassed the builder validation and passed 0.

Common situations: Config-driven values where 0 was intended to mean 'disabled'; test code instantiating the class directly; double rounding producing 0 (e.g. Integer.parseInt("0")/100.0).

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