apache/pulsar · error · IllegalArgumentException
maxRedeliverCount must be >= 0
Error message
maxRedeliverCount must be >= 0
What it means
DeadLetterPolicy requires maxRedeliverCount >= 0 because it defines how many redelivery attempts occur before a message is routed to the dead-letter topic; 0 means immediate dead-lettering and negative values have no meaning. The constructor throws IllegalArgumentException for negative values.
Source
Thrown at pulsar-client-api-v5/src/main/java/org/apache/pulsar/client/api/v5/config/DeadLetterPolicy.java:44
*
* <p>When a message has been redelivered more than {@code maxRedeliverCount} times,
* it is moved to the dead letter topic instead of being redelivered again.
*
* <p>Construct via {@link #builder()}.
*/
@EqualsAndHashCode
@ToString
public final class DeadLetterPolicy {
private final int maxRedeliverCount;
private final String retryLetterTopic;
private final String deadLetterTopic;
private final String initialSubscriptionName;
private DeadLetterPolicy(int maxRedeliverCount, String retryLetterTopic,
String deadLetterTopic, String initialSubscriptionName) {
if (maxRedeliverCount < 0) {
throw new IllegalArgumentException("maxRedeliverCount must be >= 0");
}
this.maxRedeliverCount = maxRedeliverCount;
this.retryLetterTopic = retryLetterTopic;
this.deadLetterTopic = deadLetterTopic;
this.initialSubscriptionName = initialSubscriptionName;
}
/**
* @return the maximum number of redelivery attempts before sending to the dead letter topic
*/
public int maxRedeliverCount() {
return maxRedeliverCount;
}
/**
* @return the custom retry letter topic, or {@code null} for the auto-generated default
*/
public String retryLetterTopic() {View on GitHub (pinned to 820761864e)
Solutions
- Set maxRedeliverCount to 0 or a positive integer (e.g. 3 for three redeliveries before DLQ).
- If you meant 'unlimited redeliveries', do not use a negative number - omit dead-letter routing or use a large positive cap.
- Clamp or reject negative config values at load time: Math.max(0, configuredCount).
Example fix
// before
DeadLetterPolicy dlp = DeadLetterPolicy.builder()
.maxRedeliverCount(-1) // IllegalArgumentException
.build();
// after
DeadLetterPolicy dlp = DeadLetterPolicy.builder()
.maxRedeliverCount(3)
.build(); Defensive patterns
Strategy: validation
Validate before calling
int count = cfg.maxRedeliverCount();
if (count < 0) {
throw new IllegalArgumentException("maxRedeliverCount must be >= 0, got: " + count);
}
DeadLetterPolicy dlp = DeadLetterPolicy.builder().maxRedeliverCount(count).build(); Type guard
static boolean isValidMaxRedeliverCount(int v) { return v >= 0; } Try / catch
try {
dlp = DeadLetterPolicy.builder().maxRedeliverCount(cfg).build();
} catch (IllegalArgumentException e) {
log.warn("Invalid maxRedeliverCount, using default DLQ policy", e);
dlp = DeadLetterPolicy.builder().build();
} Prevention
- Don't use -1 to mean 'unlimited'; this policy has no unlimited semantics.
- Clamp config-derived retry counts with Math.max(0, value).
- Validate DLQ settings at consumer construction time.
When it happens
Trigger: Calling DeadLetterPolicy.builder().maxRedeliverCount(-1) or passing a negative value computed from config; sentinel -1 used for 'unlimited' or 'unset'.
Common situations: Using -1 to mean 'never dead-letter' (unsupported semantics here); config parsing an empty string into a negative default; arithmetic on retry counters that can go negative.
Understand the failure class
Background: "Invalid configuration value" and "Unsupported/Unknown setting value" errors: why libraries reject your config strings, numbers, and types — this error's family across 30 libraries.
Related errors
- AutoScaledReceiverQueueSize is not supported in ZeroQueueCon
- ${key} already exists in the dynamicConfigurationMap
- configuredService should not be an instance of SystemTopicBa
- The ${alg.name()} algorithm does not support Key Pairs.
- Secret/Public Key file ${keyConfUrl} doesn't exist
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/3517d23dcc72df37.
Report an issue: GitHub.