{"record":{"id":"6d09d9ea08c6e172","repo":"apache/pulsar","slug":"timeout-must-not-be-null","errorCode":null,"errorMessage":"timeout must not be null","messagePattern":"timeout must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client-api-v5/src/main/java/org/apache/pulsar/client/api/v5/config/ProcessingTimeoutPolicy.java","lineNumber":53,"sourceCode":" *\n * <p>Disabled by default. Pass to\n * {@link org.apache.pulsar.client.api.v5.QueueConsumerBuilder#processingTimeout(ProcessingTimeoutPolicy)}\n * when the application's processing time is bounded and you want stalled deliveries to\n * be reattempted automatically.\n *\n * <p>Use {@link #of(Duration)} for the common case (no extra backoff), or\n * {@link #builder()} to also configure {@code redeliveryBackoff}.\n */\n@EqualsAndHashCode\n@ToString\npublic final class ProcessingTimeoutPolicy {\n\n    private final Duration timeout;\n    private final BackoffPolicy redeliveryBackoff;\n\n    private ProcessingTimeoutPolicy(Duration timeout, BackoffPolicy redeliveryBackoff) {\n        if (timeout == null) {\n            throw new IllegalArgumentException(\"timeout must not be null\");\n        }\n        if (timeout.isNegative()) {\n            throw new IllegalArgumentException(\"timeout must not be negative\");\n        }\n        this.timeout = timeout;\n        this.redeliveryBackoff = redeliveryBackoff;\n    }\n\n    /**\n     * @return how long the client waits for the application to ack a delivery before\n     *         requesting redelivery; {@link Duration#ZERO} disables\n     */\n    public Duration timeout() {\n        return timeout;\n    }\n\n    /**\n     * @return optional backoff applied between redeliveries, or {@code null} for the","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-api-v5/src/main/java/org/apache/pulsar/client/api/v5/config/ProcessingTimeoutPolicy.java#L35-L71","documentation":"ProcessingTimeoutPolicy's private constructor validates that the processing timeout is non-null before creating the policy object. The Apache Pulsar v5 client API requires an explicit, finite timeout for message processing/redelivery; a null timeout would leave the policy in an undefined state, so the builder rejects it eagerly with IllegalArgumentException.","triggerScenarios":"Calling ProcessingTimeoutPolicy.builder().build() or of(null) (any factory/builder path) without ever setting a timeout via .timeout(Duration) so that the private constructor receives a null Duration.","commonSituations":"Developers copying a builder snippet but omitting the .timeout(...) call, or passing a Duration field that is null because it was read from an unset config property.","solutions":["Call .timeout(Duration.ofSeconds(30)) (or your desired duration) on the ProcessingTimeoutPolicy builder before build()","If the timeout comes from configuration, supply a default when the config value is missing, e.g. Objects.requireNonNullElse(configured, Duration.ofSeconds(30))"],"exampleFix":"// before\nProcessingTimeoutPolicy policy = ProcessingTimeoutPolicy.builder().build();\n// after\nProcessingTimeoutPolicy policy = ProcessingTimeoutPolicy.builder()\n        .timeout(Duration.ofSeconds(30))\n        .build();","handlingStrategy":"validation","validationCode":"if (timeout == null) {\n    throw new IllegalArgumentException(\"ProcessingTimeoutPolicy requires a timeout; pass e.g. Duration.ofSeconds(30)\");\n}\nProcessingTimeoutPolicy.builder().timeout(timeout).build();","typeGuard":"boolean hasValidTimeout(Duration d) { return d != null && !d.isNegative(); }","tryCatchPattern":"try {\n    policy = ProcessingTimeoutPolicy.builder().timeout(timeout).build();\n} catch (IllegalArgumentException e) {\n    log.error(\"Invalid processing timeout policy: {}\", e.getMessage());\n    policy = ProcessingTimeoutPolicy.builder().timeout(Duration.ofSeconds(30)).build();\n}","preventionTips":["Always set .timeout(...) explicitly in the builder chain","Use a constant default Duration in config loaders","Validate config-derived Durations before constructing policies"],"tags":["java","validation","null-argument","client-config"],"backgroundTag":"null-argument-validation","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"}