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

  1. Re-window one PCollection to match the other (either both GlobalWindows or both the same event-time WindowFn) before merging.
  2. If event-time alignment is required, window the global side with the same WindowFn as the other input.
  3. If global windows are correct, convert the other input via Window.into(GlobalWindows()) (and reassign timestamps as needed) before the join.
  4. 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

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


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();
  }

  @AutoValue

View on GitHub (pinned to 12126d8942)