apache/beam · error · IllegalArgumentException
Window coders must be deterministic.
Error message
Window coders must be deterministic.
What it means
Window.into requires the target WindowFn's window coder to be deterministic, because Beam shuffles/retries elements and window values must serialize identically each time. If the coder's verifyDeterministic throws NonDeterministicException, Window.into wraps it in an IllegalArgumentException so the failure surfaces at transform construction time.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Window.java:186
*/
FIRE_ALWAYS,
/** Only fire the on-time pane if there is new data since the previous firing. */
FIRE_IF_NON_EMPTY
}
/**
* Creates a {@code Window} {@code PTransform} that uses the given {@link WindowFn} to window the
* data.
*
* <p>The resulting {@code PTransform}'s types have been bound, with both the input and output
* being a {@code PCollection<T>}, inferred from the types of the argument {@code WindowFn}. It is
* ready to be applied, or further properties can be set on it first.
*/
public static <T> Window<T> into(WindowFn<? super T, ?> fn) {
try {
fn.windowCoder().verifyDeterministic();
} catch (NonDeterministicException e) {
throw new IllegalArgumentException("Window coders must be deterministic.", e);
}
return Window.<T>configure().withWindowFn(fn);
}
/**
* Returns a new builder for a {@link Window} transform for setting windowing parameters other
* than the windowing function.
*/
public static <T> Window<T> configure() {
return new AutoValue_Window.Builder<T>().build();
}
public abstract @Nullable WindowFn<? super T, ?> getWindowFn();
abstract @Nullable Trigger getTrigger();
abstract @Nullable AccumulationMode getAccumulationMode();
View on GitHub (pinned to 12126d8942)
Solutions
- Make the custom window coder deterministic: encode fields in a canonical order with stable encodings
- Use Coder.verifyDeterministic to list offending components and fix them (e.g. sort collections before encoding)
- Replace non-deterministic components (doubles via bit-pattern, maps, sets) with ordered/deterministic equivalents
- If you cannot fix the coder, choose a different WindowFn with a deterministic coder
Example fix
// before
class MyWindowCoder extends CustomCoder<MyWindow> {
void encode(MyWindow w, OutputStream out) { new HashSetCoder<>(StringUtf8Coder.of()).encode(w.tags, out); } // non-deterministic
}
// after
void encode(MyWindow w, OutputStream out) {
List<String> sorted = new ArrayList<>(w.tags);
Collections.sort(sorted);
ListCoder.of(StringUtf8Coder.of()).encode(sorted, out);
} Defensive patterns
Strategy: validation
Validate before calling
try { fn.windowCoder().verifyDeterministic(); } catch (NonDeterministicException e) { throw new IllegalArgumentException("WindowFn " + fn + " has non-deterministic coder", e); } Type guard
boolean hasDeterministicWindowCoder(WindowFn<?,?> fn) { try { fn.windowCoder().verifyDeterministic(); return true; } catch (NonDeterministicException e) { return false; } } Try / catch
try { return Window.into(fn); } catch (IllegalArgumentException e) { if (e.getCause() instanceof NonDeterministicException) { LOG.error("Fix window coder determinism", e); } throw e; } Prevention
- Always call verifyDeterministic() in custom coder unit tests
- Avoid Set/Map coders and hash/toString(double) encodings in window coders
- Sort or canonicalize collections before encoding
- Derive custom coders from deterministic primitive coders only
When it happens
Trigger: Calling Window.into(fn) (or Window.configure().withWindowFn(fn)) where fn.windowCoder() declares NonDeterministicException — e.g. a custom WindowFn whose coder encodes unordered sets or object hashes.
Common situations: Custom WindowFn development with a hand-rolled coder (e.g. one backed by String.valueOf(double) or HashSet ordering); third-party windowfns with non-deterministic coders; pipelines failing at construction before any data flows.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- the keyCoder of a GroupByEncryptedKey must be deterministic
- the keyCoder of a GroupByKey must be deterministic
- the secondary key coder of SortValues must be deterministic
- DatadogWriteError can hold arbitrary instances, which may be
- SplunkEvent can hold arbitrary instances, which may be non-d
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/1bc5bf72a0a44946.
Report an issue: GitHub.