apache/beam · error · IllegalArgumentException
FixedWindows WindowingStrategies must have 0 <= offset <…
Error message
FixedWindows WindowingStrategies must have 0 <= offset < size
What it means
FixedWindows.of(...).withOffset(Duration) constructs a FixedWindows whose offset must satisfy 0 <= offset < size. The private constructor validates this and throws IllegalArgumentException otherwise, because an offset >= size is equivalent to a different window size and would corrupt window alignment.
Solutions
- Ensure offset >= Duration.ZERO and strictly less than the window size before calling withOffset.
- If the desired offset exceeds size, shrink it modulo the size (offset % size) or redefine the window size.
- Validate user-provided size/offset config at startup with a clear error message.
- Use Durations.ofX helpers consistently to avoid unit mistakes between size and offset.
Example fix
// before Duration size = Durations.minutes(5); Duration offset = Durations.minutes(10); // offset >= size -> IllegalArgumentException FixedWindows win = FixedWindows.of(size).withOffset(offset); // after Duration offset = Durations.minutes(3); checkArgument(offset.isShorterThan(size) && !offset.isShorterThan(Duration.ZERO), "0 <= offset < size"); FixedWindows win = FixedWindows.of(size).withOffset(offset);
Defensive patterns
Strategy: validation
Validate before calling
public static FixedWindows safeFixedWindows(Duration size, Duration offset) {
checkArgument(!offset.isShorterThan(Duration.ZERO), "offset must be >= 0");
checkArgument(offset.isShorterThan(size), "offset must be < size (got %s >= %s)", offset, size);
return FixedWindows.of(size).withOffset(offset);
} Try / catch
try {
return FixedWindows.of(size).withOffset(offset);
} catch (IllegalArgumentException e) {
LOG.warn("Invalid fixed-window offset {} for size {}; using offset %% size", offset, size);
return FixedWindows.of(size).withOffset(offset.minus(size.dividedBy(
size.getMillis() <= 0 ? 1 : size.getMillis() / Math.max(1, size.getMillis() / Math.max(1, offset.getMillis() / size.getMillis() == 0 ? 1 : 0)))));
} Prevention
- Validate size/offset coming from user config before building windows.
- Keep offset and size in the same Duration units (use Durations helpers).
- Reduce any desired offset modulo the window size.
- Add a startup config check: 0 <= offset < size.
When it happens
Trigger: Calling FixedWindows.of(Duration.ofMinutes(5)).withOffset(Duration.ofMinutes(10)) or withOffset(Duration.ofMinutes(-1)) — negative offset, or offset equal to or larger than the window size.
Common situations: Building windows from user-supplied config where offset and size come from separate settings without a cross-check; passing offset in the wrong unit (seconds vs minutes) so it silently exceeds the size.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- A schema was provided without a data format (or viceversa)…
- Attempted to get side input window for GlobalWindow from…
- Attempted to get side input window for GlobalWindow from…
- Batch size is too large! It should be smaller or equal than
- boolean cross product parameter required to explode more…
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/a69cb41fc6b169cf.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/FixedWindows.java:66
* where 0 is the epoch.
*/
public static FixedWindows of(Duration size) {
return new FixedWindows(size, Duration.ZERO);
}
/**
* Partitions the timestamp space into half-open intervals of the form [N * size + offset, (N + 1)
* * size + offset), where 0 is the epoch.
*
* @throws IllegalArgumentException if offset is not in [0, size)
*/
public FixedWindows withOffset(Duration offset) {
return new FixedWindows(size, offset);
}
private FixedWindows(Duration size, Duration offset) {
if (offset.isShorterThan(Duration.ZERO) || !offset.isShorterThan(size)) {
throw new IllegalArgumentException(
"FixedWindows WindowingStrategies must have 0 <= offset < size");
}
this.size = size;
this.offset = offset;
}
@Override
public IntervalWindow assignWindow(Instant timestamp) {
Instant start =
new Instant(
timestamp.getMillis()
- timestamp.plus(size).minus(offset).getMillis() % size.getMillis());
// The global window is inclusive of max timestamp, while interval window excludes its
// upper bound
Instant endOfGlobalWindow = GlobalWindow.INSTANCE.maxTimestamp().plus(Duration.millis(1));
// The end of the window is either start + size if that is within the allowable range, otherwiseView on GitHub (pinned to 12126d8942)