StreamEntryID cannot parse stream IDs in the upper half of the unsigned 64-bit range
Redis stream IDs are a pair of unsigned 64-bit integers (<ms>-<seq>); the server parses and stores them with string2ull and accepts explicit IDs across the whole range via XADD key <id> .... StreamEntryID parses them with signed Long.parseLong:
public StreamEntryID(String id) {
String[] split = id.split("-");
this.time = Long.parseLong(split[0]);
this.sequence = Long.parseLong(split[1]);
}Anything above 2^63-1 throws NumberFormatException. BuilderFactory.STREAM_ENTRY_ID and every stream reply builder (STREAM_ENTRY, STREAM_ENTRY_LIST, STREAM_PENDING_ENTRY_LIST, group/consumer full-info) construct the ID through this constructor, so once such an entry exists the stream becomes unreadable from Jedis: XRANGE/XREVRANGE/XREAD/XPENDING/XINFO all die in the builder rather than returning data.
toString() (time + "-" + sequence) and compareTo (Long.compare) have the same signed assumption, so an ID in the upper half also re-serialises as a negative decimal and sorts incorrectly.
Realistic scenario
Applications that assign explicit stream IDs — for idempotency, or to carry an external/ordering value in the ms field — can legitimately land in the upper half of the range, and a max-sequence entry (<ms>-18446744073709551615) is a valid single write. Jedis writes the ID happily (XAddParams.id(String) passes it through) but can no longer read the stream back.
Minimal reproducible example
Pure client-side (no server):
new StreamEntryID("0-18446744073709551615");
// java.lang.NumberFormatException: For input string: "18446744073709551615"Server-backed:
jedis.xadd("s", new XAddParams().id("0-18446744073709551615"), Collections.singletonMap("f", "v")); // OK
jedis.xrange("s", "-", "+"); // NumberFormatException in BuilderFactory.STREAM_ENTRYSuggested fix
Parse/format/compare the two components as unsigned (Long.parseUnsignedLong, Long.toUnsignedString, Long.compareUnsigned). This is a strict superset: every ID in the signed range parses, prints and orders exactly as before, and the upper half now round-trips instead of throwing.
I have a patch with a regression test and can open a PR.
Source: redis/jedis