apache/beam · error · NonDeterministicException

Ordering of entries in a Map may be non-deterministic.

Error message

Ordering of entries in a Map may be non-deterministic.

What it means

SortedMapCoder.verifyDeterministic() throws NonDeterministicException by default with this message. Although a SortedMap's key order is defined, Beam conservatively refuses to mark it deterministic (the generic Map message) unless the coder is explicitly verified via a subclass override; any grouping operation using this coder fails validation.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/coders/SortedMapCoder.java:152

   * {@inheritDoc}
   *
   * @return a {@link List} containing the key coder at index 0 at the and value coder at index 1.
   */
  @Override
  public List<? extends Coder<?>> getCoderArguments() {
    return Arrays.asList(keyCoder, valueCoder);
  }

  /**
   * {@inheritDoc}
   *
   * @throws NonDeterministicException always. Not all maps have a deterministic encoding. For
   *     example, {@code HashMap} comparison does not depend on element order, so two {@code
   *     HashMap} instances may be equal but produce different encodings.
   */
  @Override
  public void verifyDeterministic() throws NonDeterministicException {
    throw new NonDeterministicException(
        this, "Ordering of entries in a Map may be non-deterministic.");
  }

  @Override
  public boolean consistentWithEquals() {
    return keyCoder.consistentWithEquals() && valueCoder.consistentWithEquals();
  }

  @Override
  public Object structuralValue(SortedMap<K, V> value) {
    if (consistentWithEquals()) {
      return value;
    } else {
      Map<Object, Object> ret = Maps.newHashMapWithExpectedSize(value.size());
      for (Map.Entry<K, V> entry : value.entrySet()) {
        ret.put(
            keyCoder.structuralValue(entry.getKey()), valueCoder.structuralValue(entry.getValue()));
      }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Override verifyDeterministic in a custom coder subclass that checks keyCoder and valueCoder determinism (as Beam's own verified coders do) and use that coder
  2. Use KV<K,V> with deterministic key/value coders instead of a Map
  3. Encode as a sorted List of KVs with ListCoder for deterministic grouping

Example fix

// before
Coder<SortedMap<K,V>> c = SortedMapCoder.of(kCoder, vCoder);
c.verifyDeterministic(); // throws
// after
public class VerifiedSortedMapCoder<K,V> extends SortedMapCoder<K,V> {
  @Override public void verifyDeterministic() throws NonDeterministicException {
    verifyDeterministic(keyCoder, "key coder", (m) -> m.entrySet());
    verifyDeterministic(valueCoder, "value coder", (m) -> m.values());
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

try { sortedMapCoder.verifyDeterministic(); } catch (NonDeterministicException e) { /* use KV or verified custom coder */ }

Type guard

null

Try / catch

try { coder.verifyDeterministic(); } catch (NonDeterministicException e) { use custom subclass that verifies key/value coders }

Prevention

When it happens

Trigger: Using SortedMapCoder as key/element coder in GroupByKey, Combine, or calling verifyDeterministic() during pipeline validation.

Common situations: Grouping keyed by a TreeMap; pipeline submit-time determinism validation; tests calling verifyDeterministic on Map-like coders.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/a82ceb447f407d0b. Report an issue: GitHub.