apache/pulsar · error · IllegalArgumentException
timeout must not be null
Error message
timeout must not be null
What it means
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.
Source
Thrown at pulsar-client-api-v5/src/main/java/org/apache/pulsar/client/api/v5/config/ProcessingTimeoutPolicy.java:53
*
* <p>Disabled by default. Pass to
* {@link org.apache.pulsar.client.api.v5.QueueConsumerBuilder#processingTimeout(ProcessingTimeoutPolicy)}
* when the application's processing time is bounded and you want stalled deliveries to
* be reattempted automatically.
*
* <p>Use {@link #of(Duration)} for the common case (no extra backoff), or
* {@link #builder()} to also configure {@code redeliveryBackoff}.
*/
@EqualsAndHashCode
@ToString
public final class ProcessingTimeoutPolicy {
private final Duration timeout;
private final BackoffPolicy redeliveryBackoff;
private ProcessingTimeoutPolicy(Duration timeout, BackoffPolicy redeliveryBackoff) {
if (timeout == null) {
throw new IllegalArgumentException("timeout must not be null");
}
if (timeout.isNegative()) {
throw new IllegalArgumentException("timeout must not be negative");
}
this.timeout = timeout;
this.redeliveryBackoff = redeliveryBackoff;
}
/**
* @return how long the client waits for the application to ack a delivery before
* requesting redelivery; {@link Duration#ZERO} disables
*/
public Duration timeout() {
return timeout;
}
/**
* @return optional backoff applied between redeliveries, or {@code null} for theView on GitHub (pinned to 820761864e)
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))
Example fix
// before
ProcessingTimeoutPolicy policy = ProcessingTimeoutPolicy.builder().build();
// after
ProcessingTimeoutPolicy policy = ProcessingTimeoutPolicy.builder()
.timeout(Duration.ofSeconds(30))
.build(); Defensive patterns
Strategy: validation
Validate before calling
if (timeout == null) {
throw new IllegalArgumentException("ProcessingTimeoutPolicy requires a timeout; pass e.g. Duration.ofSeconds(30)");
}
ProcessingTimeoutPolicy.builder().timeout(timeout).build(); Type guard
boolean hasValidTimeout(Duration d) { return d != null && !d.isNegative(); } Try / catch
try {
policy = ProcessingTimeoutPolicy.builder().timeout(timeout).build();
} catch (IllegalArgumentException e) {
log.error("Invalid processing timeout policy: {}", e.getMessage());
policy = ProcessingTimeoutPolicy.builder().timeout(Duration.ofSeconds(30)).build();
} Prevention
- Always set .timeout(...) explicitly in the builder chain
- Use a constant default Duration in config loaders
- Validate config-derived Durations before constructing policies
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- timeout must not be negative
- at least one key name must be configured
- timeout must be > 0
- Timeout during delete operation
- Timeout during close operation
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/6d09d9ea08c6e172.
Report an issue: GitHub.