{"record":{"id":"3134d15e2d5b9d17","repo":"apache/beam","slug":"java-serialization-may-be-non-deterministic","errorCode":null,"errorMessage":"Java Serialization may be non-deterministic.","messagePattern":"Java Serialization may be non-deterministic\\.","errorType":"exception","errorClass":"NonDeterministicException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/coders/SerializableCoder.java","lineNumber":214,"sourceCode":"  @Override\n  public T decode(InputStream inStream) throws IOException, CoderException {\n    try {\n      ObjectInputStream ois = new ObjectInputStream(inStream);\n      return type.cast(ois.readObject());\n    } catch (ClassNotFoundException e) {\n      throw new CoderException(\"unable to deserialize record\", e);\n    }\n  }\n\n  /**\n   * {@inheritDoc}\n   *\n   * @throws NonDeterministicException always. Java serialization is not deterministic with respect\n   *     to {@link Object#equals} for all types.\n   */\n  @Override\n  public void verifyDeterministic() throws NonDeterministicException {\n    throw new NonDeterministicException(this, \"Java Serialization may be non-deterministic.\");\n  }\n\n  @Override\n  @SuppressWarnings(\"EqualsGetClass\")\n  public boolean equals(@Nullable Object other) {\n    return !(other == null || getClass() != other.getClass())\n        && type == ((SerializableCoder<?>) other).type;\n  }\n\n  @Override\n  public int hashCode() {\n    return type.hashCode();\n  }\n\n  @Override\n  public TypeDescriptor<T> getEncodedTypeDescriptor() {\n    if (typeDescriptor == null) {\n      typeDescriptor = TypeDescriptor.of(type);","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/SerializableCoder.java#L196-L232","documentation":"SerializableCoder.verifyDeterministic() always throws NonDeterministicException: Java serialization output is not guaranteed to be byte-identical for equal objects (field order, writeObject overrides, identity handling), so Beam cannot treat SerializableCoder as deterministic. Operations requiring deterministic keys reject it.","triggerScenarios":"Using SerializableCoder for a key or element in determinism-sensitive operations like GroupByKey, or calling verifyDeterministic() during CoderRegistry validation.","commonSituations":"Grouping POJOs encoded with SerializableCoder; switching a deterministic custom coder to SerializableCoder and failing pipeline validation.","solutions":["Write a custom deterministic Coder<T> (fixed field order, canonical representation) and use it for keys","Use AvroCoder.of(T.class) or schema-based RowCoder, which have deterministic encodings","Convert the key type to a primitive/String that Beam can encode deterministically"],"exampleFix":"// before\n.apply(WithKeys.of(rec -> rec)) // SerializableCoder<MyRec> key -> NonDeterministicException\n// after\n.apply(WithKeys.of(rec -> rec.getId())) // String key, deterministic coder","handlingStrategy":"try-catch","validationCode":"try { coder.verifyDeterministic(); } catch (NonDeterministicException e) { /* pick deterministic coder */ }","typeGuard":"null","tryCatchPattern":"try { coder.verifyDeterministic(); } catch (NonDeterministicException e) { switch to AvroCoder or custom deterministic coder }","preventionTips":["Never use SerializableCoder for grouping keys","Unit-test coders with CoderProperties for determinism","Use schema-based coders for POJOs"],"tags":["java","beam","coders","determinism","serialization"],"backgroundTag":"unsupported-operation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}