pandas-dev/pandas · error · ValueError
Start/End ordering requirement is violated at index {i}
Error message
Start/End ordering requirement is violated at index {i} What it means
This error is raised inside the Numba-accelerated kernel for rolling minimum/maximum calculations (engine="numba"). The kernel processes windowed extrema using a monotonicity assumption: each successive window's end-boundary must strictly advance, or if the end stays the same, the start must not decrease. This invariant lets the deque-based algorithm run in O(N) rather than re-scanning. When the start/end boundary arrays passed to the kernel violate this ordering, the algorithm cannot produce correct results and aborts.
Source
Thrown at pandas/core/_numba/kernels/min_max_.py:96
i_next = i
# NaN tracking to guarantee min_periods
valid_start = -min_periods
last_end = 0
last_start = -1
for i in range(N):
this_start = start[i].item()
this_end = end[i].item()
if dominators and dominators[-1] == i:
dominators.pop()
if not (
this_end > last_end or (this_end == last_end and this_start >= last_start)
):
raise ValueError(
"Start/End ordering requirement is violated at index " + str(i)
)
stash_start = (
this_start if not dominators else min(this_start, start[dominators[-1]])
)
while candidates and candidates[0] < stash_start:
candidates.pop(0)
for k in range(last_end, this_end):
if not np.isnan(values[k]):
valid_start += 1
while valid_start >= 0 and np.isnan(values[valid_start]):
valid_start += 1
while candidates and cmp(values[k], values[candidates[-1]], is_max):
candidates.pop() # Q.pop_back()
candidates.append(k) # Q.push_back(k)
View on GitHub (pinned to 3b7651241d)
Solutions
- Switch to the default engine (remove engine="numba" or set engine="cython") which has looser ordering requirements.
- Ensure your window boundaries are sorted so that end[i] is strictly increasing, or non-decreasing with non-decreasing start when ends are equal, before passing them to the rolling operation.
- If using variable windows, pre-sort or reindex your data so windows advance monotonically, then re-map results back to the original order.
- Verify your pandas version — newer versions may relax or tighten these constraints; check the release notes for rolling numba changes.
Example fix
# before s.rolling(window=custom_bounds, engine="numba").min() # after — use default engine which accepts arbitrary window orderings s.rolling(window=custom_bounds).min()
Defensive patterns
Strategy: validation
Validate before calling
# Before calling rolling min/max with numba, verify window ordering
start = np.asarray(start_bounds)
end = np.asarray(end_bounds)
for i in range(1, len(end)):
if not (end[i] > end[i-1] or (end[i] == end[i-1] and start[i] >= start[i-1])):
raise ValueError(f"Window ordering violated at index {i}; use default engine") Try / catch
try:
result = s.rolling(window=bounds, engine="numba").min()
except ValueError as e:
if "Start/End ordering" in str(e):
# fall back to default engine
result = s.rolling(window=bounds).min()
else:
raise Prevention
- Prefer the default Cython engine for rolling operations unless you specifically need Numba performance.
- Sort or reindex your data so window boundaries advance monotonically before using engine='numba'.
- Check the pandas release notes when upgrading — numba rolling constraints may change between versions.
When it happens
Trigger: Calling Series.rolling(...).min(engine="numba") or .max(engine="numba") with variable-length or forward-looking window definitions whose boundary arrays are not monotonically ordered by end (and non-decreasing by start when ends tie). This arises with custom window generators, forward windows, or manually constructed start/end index arrays that interleave or reverse.
Common situations: Using Rolling/Expanding with a step parameter or custom window array alongside engine="numba" in a pandas version where the numba path has stricter ordering constraints than the default Cython path. Migrating from the default engine to engine="numba" and discovering the window semantics differ. Constructing windows from irregular time-series boundaries (e.g., session-based or event-based windows) where end boundaries can revisit or stay flat while starts move backwards.
Related errors
- Column {colname} must have a numeric dtype. Found '{dtype}'
- Column {colname} is backed by an extension array, which is n
- periods must be an integer
- cannot diff {type(arr).__name__} on axis={axis}
- values should be unique if codes is not None
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/cc687e30fac4ad14.
Report an issue: GitHub.