You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: Java FlinkRunner OrderedListState silently overwrites duplicate elements sharing same timestamps #39782
When executing a pipeline using the FlinkRunner (specifically observed using the HashMapStateBackend / Java heap state configuration), adding multiple distinct elements with the exact same timestamp to an OrderedListState results in critical data loss. The last element written completely overwrites any previous elements that shared that specific millisecond timestamp bucket.
According to Beam's core architectural contract, OrderedListState should preserve and sort all appended values. It does not impose an invariant rule requiring timestamps to be globally unique.
The underlying flaw stems from how FlinkStateInternals maps OrderedListState onto Flink's native primitive structures. The runner sets the key of Flink's internal tracking storage structure to the Long timestamp value itself. During back-to-back writes in a single execution bundle, the internal write-buffer performs a flat replacement (equivalent to a map put action) instead of appending the element to a sub-collection (like a List) associated with that timestamp bucket.
Expected Behavior
OrderedListState should treat the timestamp solely as a sorting key index. If multiple elements share a timestamp, the runner's underlying serialization layout must wrap elements in an appendable multi-value collection (e.g., mapping to a Flink MapState<Long, List<T>>) so that subsequent writes do not execute a flat destructive overwrite.
Actual Behavior
The second write ("Ball") silently destroys and overwrites the initial write ("Apple") at the timestamp boundary level inside the Java heap state backend.
The problem is that FlinkOrderedListState.readAsMap() returns Map<Instant, TimestampedValue<T>>, which prevents multiple records with the same Instant. This would have to be changed to MultiMap , PriorityQueue or similar approach. Also there is missing @ValidatesRunner suite that will cover this behavior.
Overall (due to missing equivalent in Flink state primitives) the implementation is quite inefficient (mostly if the list grows larger), as it sorts the complete list on every read() or readRange().
Activity
je-ik commentedon Aug 17, 2026
The problem is that
FlinkOrderedListState.readAsMap()returnsMap<Instant, TimestampedValue<T>>, which prevents multiple records with the same Instant. This would have to be changed toMultiMap,PriorityQueueor similar approach. Also there is missing@ValidatesRunnersuite that will cover this behavior.Overall (due to missing equivalent in Flink state primitives) the implementation is quite inefficient (mostly if the list grows larger), as it sorts the complete list on every
read()orreadRange().je-ik commentedon Sep 8, 2026
Should the duplicate PR be closed? #39795