apache/pulsar · error · IllegalArgumentException
delta at index ${i} must be >= 0, got ${deltas.get(i)}
Error message
delta at index ${i} must be >= 0, got ${deltas.get(i)} What it means
IllegalArgumentException thrown by the SequenceKeysDeltas compact constructor when any delta after index 0 is negative. Later deltas represent gaps between consecutive sequence keys and must be non-negative; a negative delta would mean sequence keys went backwards, which the library treats as a data-integrity violation.
Source
Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/api/Option.java:98
* <p>Constraints: {@code deltas} must be non-empty, the first delta must be {@code > 0}, and
* the rest must be {@code >= 0}. On Oxia a {@link PartitionKey} must also be provided.
* Backends without native sequence-key support synthesize the same key format using a
* sidecar counter document and CAS.
*
* @param deltas per-dimension increments
*/
record SequenceKeysDeltas(List<Long> deltas) implements Option {
public SequenceKeysDeltas {
if (deltas == null || deltas.isEmpty()) {
throw new IllegalArgumentException("SequenceKeysDeltas requires at least one delta");
}
if (deltas.get(0) <= 0) {
throw new IllegalArgumentException("first delta must be > 0, got " + deltas.get(0));
}
for (int i = 1; i < deltas.size(); i++) {
if (deltas.get(i) < 0) {
throw new IllegalArgumentException(
"delta at index " + i + " must be >= 0, got " + deltas.get(i));
}
}
deltas = List.copyOf(deltas);
}
}
}
View on GitHub (pinned to 820761864e)
Solutions
- Sort the sequence keys in ascending order before computing deltas
- Fix the delta computation to be (current - previous) with ascending order
- Add a pre-check that rejects negative deltas with a clearer domain error
Example fix
// before List<Long> keys = keysFromSource; // may be unsorted SequenceKeysDeltas d = new SequenceKeysDeltas(toDeltas(keys)); // throws if a diff is negative // after List<Long> sorted = keys.stream().sorted().toList(); List<Long> deltas = toDeltas(sorted); // each delta = cur - prev >= 0 SequenceKeysDeltas d = new SequenceKeysDeltas(deltas);
Defensive patterns
Strategy: validation
Validate before calling
for (int i = 1; i < deltas.size(); i++) {
if (deltas.get(i) < 0) throw new IllegalArgumentException("delta at " + i + " must be >= 0");
} Type guard
static boolean hasNonNegativeDeltas(List<Long> deltas) {
return deltas == null || deltas.stream().skip(1).allMatch(d -> d >= 0);
} Prevention
- Always sort sequence keys ascending before computing deltas
- Use cur - previous consistently, never reverse the subtraction
- Unit-test the delta builder with unsorted input
When it happens
Trigger: Constructing SequenceKeysDeltas with a list where deltas.get(i) < 0 for i >= 1, typically because keys were sorted in the wrong order (descending) or a diff was computed as earlier-minus-later key.
Common situations: Sorting keys descending instead of ascending before computing deltas; subtracting in the wrong direction; corrupted or reordered key streams.
Related errors
- first delta must be > 0, got ${deltas.get(0)}
- Timeout during update managedLedger's properties
- Failed to initialize BookKeeper metadata
- Error while scanning ledgers for ${namespaceName}
- Must have at least 1 segment
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/b444ea3f44c1a0c2.
Report an issue: GitHub.