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

  1. Align the DaysWindows parameters (number of days, startDate, timeZone) on both PCollections before the join/flatten.
  2. Extract the window parameters into shared constants/config so both sides use the same values.
  3. 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.
  4. 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

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


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)