apache/beam · error · IncompatibleWindowException
GlobalWindows is only compatible with GlobalWindows.
Error message
GlobalWindows is only compatible with GlobalWindows.
What it means
GlobalWindows.verifyCompatibility throws IncompatibleWindowException when a GlobalWindows-windowed PCollection is merged with a PCollection using any other WindowFn. Beam requires both sides of a cross-source grouping to use the same window function, and GlobalWindows is only compatible with itself.
Solutions
- Re-window one PCollection to match the other (either both GlobalWindows or both the same event-time WindowFn) before merging.
- If event-time alignment is required, window the global side with the same WindowFn as the other input.
- If global windows are correct, convert the other input via Window.into(GlobalWindows()) (and reassign timestamps as needed) before the join.
- Catch IncompatibleWindowException in pipeline setup to surface the mismatch early.
Example fix
// before PCollection<A> a = inA.apply(Window.into(FixedWindows.of(MINUTES_5))); PCollection<B> b = inB.apply(Window.into(GlobalWindows())); KeyedPCollectionTuple.of(t1, a).and(t2, b).apply(CoGroupByKey.create()); // throws // after PCollection<B> b2 = inB.apply(Window.into(FixedWindows.of(MINUTES_5))); KeyedPCollectionTuple.of(t1, a).and(t2, b2).apply(CoGroupByKey.create());
Defensive patterns
Strategy: validation
Validate before calling
public static void requireSameWindowing(WindowFn<?, ?> a, WindowFn<?, ?> b) throws IncompatibleWindowException {
a.verifyCompatibility(b); // throws if GlobalWindows is merged with any other WindowFn
} Type guard
boolean isGlobal(WindowFn<?, ?> fn) { return fn instanceof GlobalWindows; } Try / catch
try {
gw.verifyCompatibility(otherFn);
} catch (IncompatibleWindowException e) {
// re-window otherFn's PCollection to GlobalWindows or the matching event-time WindowFn
} Prevention
- Decide upfront whether merges happen in global or event-time windows and standardize.
- Remember GlobalWindows is only compatible with itself; convert one side explicitly.
- After aggregations that emit GlobalWindows, re-window before joining with windowed inputs.
- Add pipeline-construction asserts calling verifyCompatibility.
When it happens
Trigger: CoGroupByKey/Flatten between a PCollection with Window.into(GlobalWindows()) and one windowed with FixedWindows/SlidingWindows/CalendarWindows (or vice versa).
Common situations: Joining an unbounded stream that was explicitly set to global windows against a calendar/fixed-windowed side input; forgetting that some transforms (e.g. after certain aggregations) leave GlobalWindows while the other input keeps event-time windows.
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
- Only FixedWindows objects with the same size and offset are…
- Only objects with the same number of days, start date and…
- 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/1949caa7225fdfd5.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/GlobalWindows.java:53
public class GlobalWindows extends NonMergingWindowFn<Object, GlobalWindow> {
private static final Collection<GlobalWindow> GLOBAL_WINDOWS =
Collections.singletonList(GlobalWindow.INSTANCE);
@Override
public Collection<GlobalWindow> assignWindows(AssignContext c) {
return GLOBAL_WINDOWS;
}
@Override
public boolean isCompatible(WindowFn<?, ?> o) {
return o instanceof GlobalWindows;
}
@Override
public void verifyCompatibility(WindowFn<?, ?> other) throws IncompatibleWindowException {
if (!this.isCompatible(other)) {
throw new IncompatibleWindowException(
other,
String.format(
"%s is only compatible with %s.",
GlobalWindows.class.getSimpleName(), GlobalWindows.class.getSimpleName()));
}
}
@Override
public Coder<GlobalWindow> windowCoder() {
return GlobalWindow.Coder.INSTANCE;
}
@Override
public WindowMappingFn<GlobalWindow> getDefaultWindowMappingFn() {
return new AutoValue_GlobalWindows_GlobalWindowMappingFn();
}
@AutoValueView on GitHub (pinned to 12126d8942)