{"record":{"id":"4d3467ddd005b026","repo":"apache/pulsar","slug":"earlytokenrefreshpercent-must-be-greater-than-0-4d3467","errorCode":null,"errorMessage":"EarlyTokenRefreshPercent must be greater than 0.","messagePattern":"EarlyTokenRefreshPercent must be greater than 0\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/oauth2/AuthenticationOAuth2.java","lineNumber":153,"sourceCode":"\n    AuthenticationOAuth2(Flow flow,\n                         Clock clock,\n                         double earlyTokenRefreshPercent,\n                         ScheduledExecutorService scheduler) {\n        this(clock, earlyTokenRefreshPercent, scheduler);\n        this.flow = flow;\n    }\n\n    /**\n     * @param clock - clock to use when determining token expiration.\n     * @param earlyTokenRefreshPercent - see javadoc for {@link AuthenticationOAuth2}. Must be greater than 0.\n     * @param scheduler - The scheduler to use for background token refreshes. If {@code null} and\n     *                  {@link #earlyTokenRefreshPercent} is less than 1, the shared internal daemon-thread\n     *                  scheduler is used. If the caller supplies a scheduler, this class will not shut it down.\n     */\n    private AuthenticationOAuth2(Clock clock, double earlyTokenRefreshPercent, ScheduledExecutorService scheduler) {\n        if (earlyTokenRefreshPercent <= 0) {\n            throw new IllegalArgumentException(\"EarlyTokenRefreshPercent must be greater than 0.\");\n        }\n        this.earlyTokenRefreshPercent = earlyTokenRefreshPercent;\n        this.clock = clock;\n        if (scheduler == null && earlyTokenRefreshPercent < 1) {\n            this.scheduler = INTERNAL_SCHEDULER;\n        } else {\n            this.scheduler = scheduler;\n        }\n    }\n\n    @Override\n    public String getAuthMethodName() {\n        return AUTH_METHOD_NAME;\n    }\n\n    @Override\n    public void configure(String encodedAuthParamString) {\n        Map<String, String> params = parseAuthParameters(encodedAuthParamString);","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/oauth2/AuthenticationOAuth2.java#L135-L171","documentation":"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.","triggerScenarios":"Constructing AuthenticationOAuth2 with earlyTokenRefreshPercent <= 0 through an internal/factory path, or a flow builder path that bypassed the builder validation and passed 0.","commonSituations":"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).","solutions":["Pass a value in (0,1) to enable early refresh or >= 1 to disable; never 0 or negative.","Prefer the official builder (AuthenticationFactoryOAuth2) which validates earlier with a clearer message.","Sanitize config values: treat missing/0 as 1 (disabled)."],"exampleFix":"// before\nnew AuthenticationOAuth2(clock, 0.0, null); // throws\n// after\nnew AuthenticationOAuth2(clock, 1.0, null); // >=1 disables early refresh","handlingStrategy":"validation","validationCode":"if (!(pct > 0)) {\n    pct = 1.0; // disable early refresh\n}\nAuthentication auth = AuthenticationFactoryOAuth2\n    .clientCredentials(issuerUrl, clientId, clientSecret)\n    .earlyTokenRefreshPercent(pct)\n    .build();","typeGuard":null,"tryCatchPattern":"try {\n    return buildAuth(pct);\n} catch (IllegalArgumentException e) {\n    throw new ConfigurationException(\"earlyTokenRefreshPercent must be > 0; use >= 1 to disable\", e);\n}","preventionTips":["Use the public factory/builder instead of constructing AuthenticationOAuth2 directly.","Treat 0 as invalid in config parsing and map it to 1.0 (disabled).","Beware double rounding: Integer.parseInt(\"0\")/100.0 == 0.0."],"tags":["pulsar-client","oauth2","configuration","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}