{"record":{"id":"7d018ab82031c38b","repo":"apache/pulsar","slug":"jitterpercent-must-be-in-0-100","errorCode":null,"errorMessage":"jitterPercent must be in [0, 100]","messagePattern":"jitterPercent must be in \\[0, 100\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client-api-v5/src/main/java/org/apache/pulsar/client/api/v5/config/BackoffPolicy.java","lineNumber":55,"sourceCode":"@ToString\npublic final class BackoffPolicy {\n\n    /** Default jitter percentage applied when not explicitly specified. */\n    public static final double DEFAULT_JITTER_PERCENT = 10.0;\n\n    private final Duration initialInterval;\n    private final Duration maxInterval;\n    private final double multiplier;\n    private final double jitterPercent;\n\n    private BackoffPolicy(Duration initialInterval, Duration maxInterval, double multiplier, double jitterPercent) {\n        Objects.requireNonNull(initialInterval, \"initialInterval must not be null\");\n        Objects.requireNonNull(maxInterval, \"maxInterval must not be null\");\n        if (multiplier < 1.0) {\n            throw new IllegalArgumentException(\"multiplier must be >= 1.0\");\n        }\n        if (jitterPercent < 0 || jitterPercent > 100) {\n            throw new IllegalArgumentException(\"jitterPercent must be in [0, 100]\");\n        }\n        this.initialInterval = initialInterval;\n        this.maxInterval = maxInterval;\n        this.multiplier = multiplier;\n        this.jitterPercent = jitterPercent;\n    }\n\n    /**\n     * @return the base delay before the first reconnection attempt\n     */\n    public Duration initialInterval() {\n        return initialInterval;\n    }\n\n    /**\n     * @return the maximum delay between reconnection attempts\n     */\n    public Duration maxInterval() {","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-api-v5/src/main/java/org/apache/pulsar/client/api/v5/config/BackoffPolicy.java#L37-L73","documentation":"The BackoffPolicy constructor validates that jitterPercent lies within the inclusive range 0-100. Jitter is expressed as a percentage of the computed backoff delay used to randomize retries and avoid thundering herds; a value outside [0,100] is meaningless (negative jitter or >100% would exceed the base delay). The library throws IllegalArgumentException immediately at construction so misconfiguration fails fast.","triggerScenarios":"Calling new BackoffPolicy(initialInterval, maxInterval, multiplier, jitterPercent) or a builder method like jitterPercent(int) with a value < 0 or > 100, e.g. BackoffPolicy.builder().jitterPercent(150) or .jitterPercent(-10).","commonSituations":"Confusing jitterPercent (0-100) with a fraction (0-1) and passing 0.5 then multiplying by 100 twice; reading a value from external config where units are misdocumented; copying a multiplier-style config where 1.5 meant '50% jitter' but was entered as 150.","solutions":["Set jitterPercent to an integer in [0, 100] (e.g. 20 for 20% jitter).","If your source value is a fraction, convert it: jitterPercent = (int)(fraction * 100).","Clamp or reject the value in your config loading layer before constructing BackoffPolicy."],"exampleFix":"// before\nBackoffPolicy p = BackoffPolicy.builder()\n    .initialInterval(Duration.ofMillis(100))\n    .maxInterval(Duration.ofSeconds(30))\n    .multiplier(2.0)\n    .jitterPercent(150) // IllegalArgumentException\n    .build();\n\n// after\nBackoffPolicy p = BackoffPolicy.builder()\n    .initialInterval(Duration.ofMillis(100))\n    .maxInterval(Duration.ofSeconds(30))\n    .multiplier(2.0)\n    .jitterPercent(50) // valid: 50% jitter\n    .build();","handlingStrategy":"validation","validationCode":"int jp = config.jitterPercent();\nif (jp < 0 || jp > 100) {\n    throw new IllegalArgumentException(\"jitterPercent must be in [0, 100], got: \" + jp);\n}\nBackoffPolicy p = BackoffPolicy.builder().jitterPercent(jp).build();","typeGuard":"static boolean isValidJitterPercent(int v) { return v >= 0 && v <= 100; }","tryCatchPattern":"try {\n    policy = BackoffPolicy.builder().jitterPercent(cfg).build();\n} catch (IllegalArgumentException e) {\n    log.warn(\"Bad jitterPercent, falling back to default\", e);\n    policy = BackoffPolicy.builder().build();\n}","preventionTips":["Remember jitterPercent is a 0-100 integer percentage, not a 0-1 fraction.","Convert fractions with Math.round(fraction * 100) before passing.","Validate all retry-related config values at application startup, not at first retry."],"tags":["java","configuration","illegal-argument","retry","client-api"],"backgroundTag":"invalid-configuration-value","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}