apache/beam · error · IncompatibleWindowException
Only objects with the same number of days, start date and…
Error message
Only %s objects with the same number of days, start date and time zone are compatible.
What it means
CalendarWindows.DaysWindows.verifyCompatibility throws IncompatibleWindowException when merging/grouping streams whose WindowFn is a DaysWindows with a different number of days, start date, or time zone. Beam requires both sides of a join/GroupByKey across sources to use compatible windowing so windows line up element-wise.
Solutions
- Align the DaysWindows parameters (number of days, startDate, timeZone) on both PCollections before the join/flatten.
- Extract the window parameters into shared constants/config so both sides use the same values.
- If different calendar windows are intentional, convert one side's windows first (e.g. re-window via a Window.transform and re-assign timestamps) or use GlobalWindows for the merge.
- Catch IncompatibleWindowException during pipeline construction to fail fast with a clear configuration check.
Example fix
// before
PCollection<A> a = inputA.apply(Window.into(CalendarWindows.days(7)));
PCollection<B> b = inputB.apply(Window.into(CalendarWindows.days(14)));
PCollection<Pair> joined = KeyedPCollectionTuple.of(t1, a).and(t2, b).apply(CoGroupByKey.create());
// after
CalendarWindows.DaysWindows win = CalendarWindows.days(7, START_DATE, ZoneId.of("UTC"));
PCollection<A> a = inputA.apply(Window.into(win));
PCollection<B> b = inputB.apply(Window.into(win)); Defensive patterns
Strategy: validation
Validate before calling
DaysWindows w1 = CalendarWindows.days(7, START, ZONE);
DaysWindows w2 = (DaysWindows) other;
boolean compatible = w1.getDays() == w2.getDays()
&& w1.getStartDate().equals(w2.getStartDate())
&& w1.getTimeZone().equals(w2.getTimeZone()); Try / catch
try {
windowFn1.verifyCompatibility(windowFn2);
} catch (IncompatibleWindowException e) {
throw new IllegalStateException("Align DaysWindows params before merging: " + e.getMessage(), e);
} Prevention
- Define calendar window parameters once in shared config, not per-pipeline.
- Always specify the same timeZone explicitly (never rely on JVM default).
- Call verifyCompatibility on both WindowFns during pipeline setup for fail-fast checks.
- Before joining calendar-windowed streams, confirm days/startDate/zone match.
When it happens
Trigger: Using CalendarWindows.days(n) (with differing days(), startDate, or timeZone arguments) in a PCollection that is joined, flattened, or grouped with another PCollection using CalendarWindows.days(m) with different parameters.
Common situations: Two pipelines/PCollections built by different teams with different calendar window configs (e.g. 7 days vs 14 days, UTC vs local zone, or different startDate), then combined with CoGroupByKey or Flatten.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- GlobalWindows is only compatible with GlobalWindows.
- Only FixedWindows objects with the same size and offset are…
- Only objects with the same number of months, day of month…
- Only objects with the same number of years, month of year…
- Attempted to get side input window for GlobalWindow from…
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/71d799ba7fbdabc4.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/CalendarWindows.java:146
public Coder<IntervalWindow> windowCoder() {
return IntervalWindow.getCoder();
}
@Override
public boolean isCompatible(WindowFn<?, ?> other) {
if (!(other instanceof DaysWindows)) {
return false;
}
DaysWindows that = (DaysWindows) other;
return number == that.number
&& Objects.equals(startDate, that.startDate)
&& Objects.equals(timeZone, that.timeZone);
}
@Override
public void verifyCompatibility(WindowFn<?, ?> other) throws IncompatibleWindowException {
if (!this.isCompatible(other)) {
throw new IncompatibleWindowException(
other,
String.format(
"Only %s objects with the same number of days, start date "
+ "and time zone are compatible.",
DaysWindows.class.getSimpleName()));
}
}
@Override
public void populateDisplayData(DisplayData.Builder builder) {
super.populateDisplayData(builder);
builder
.add(DisplayData.item("numDays", number).withLabel("Windows Days"))
.addIfNotDefault(
DisplayData.item("startDate", new DateTime(startDate, timeZone).toInstant())
.withLabel("Window Start Date"),
new DateTime(DEFAULT_START_DATE, DateTimeZone.UTC).toInstant());View on GitHub (pinned to 12126d8942)