{"record":{"id":"997e624187531350","repo":"apache/beam","slug":"floating-point-encodings-are-not-guaranteed-to-be","errorCode":null,"errorMessage":"Floating point encodings are not guaranteed to be deterministic.","messagePattern":"Floating point encodings are not guaranteed to be deterministic\\.","errorType":"exception","errorClass":"NonDeterministicException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/coders/DoubleCoder.java","lineNumber":70,"sourceCode":"    try {\n      return Double.longBitsToDouble(BitConverters.readBigEndianLong(inStream));\n    } catch (EOFException | UTFDataFormatException exn) {\n      // These exceptions correspond to decoding problems, so change\n      // what kind of exception they're branded as.\n      throw new CoderException(exn);\n    }\n  }\n\n  /**\n   * {@inheritDoc}\n   *\n   * @throws NonDeterministicException always. Floating-point operations are not guaranteed to be\n   *     deterministic, even if the storage format might be, so floating point representations are\n   *     not recommended for use in operations that require deterministic inputs.\n   */\n  @Override\n  public void verifyDeterministic() throws NonDeterministicException {\n    throw new NonDeterministicException(\n        this, \"Floating point encodings are not guaranteed to be deterministic.\");\n  }\n\n  /**\n   * {@inheritDoc}\n   *\n   * @return {@code true}. This coder is injective.\n   */\n  @Override\n  public boolean consistentWithEquals() {\n    return true;\n  }\n\n  /**\n   * {@inheritDoc}\n   *\n   * @return {@code true}. {@link DoubleCoder#getEncodedElementByteSize} returns a constant.\n   */","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/DoubleCoder.java#L52-L88","documentation":"DoubleCoder.verifyDeterministic always throws NonDeterministicException because IEEE-754 floating-point encoding/behavior is not guaranteed deterministic across platforms (NaN payloads, signed zeros, hardware differences). Beam rejects such coders where determinism is required (e.g. keys for GroupByKey, state, ordering).","triggerScenarios":"Using Double (or a type whose resolved coder is DoubleCoder) as a key in GroupByKey/Combine PerKey, as state, or anywhere Beam calls coder.verifyDeterministic().","commonSituations":"Grouping computed double values; using double timestamps/scores as keys; applying Combine.perKey on KV<Double, V>.","solutions":["Convert doubles to a deterministic representation before grouping, e.g. quantize to long (Math.round(x * 1e6)) or fixed-point BigDecimal string.","Use a wrapper coder that defines a deterministic encoding and override verifyDeterministic only if you can prove determinism.","Restructure the pipeline so doubles are values, not keys.","If grouping on floats is truly required, normalize values (canonicalize NaN/-0.0) and use a custom coder."],"exampleFix":"// before\nKV<Double, String> kv = KV.of(score, id);\n... apply(GroupByKey.create()) // NonDeterministicException\n\n// after\nKV<Long, String> kv = KV.of(Math.round(score * 1_000_000L), id); // quantized key","handlingStrategy":"validation","validationCode":"try {\n  Coder<?> keyCoder = ...;\n  keyCoder.verifyDeterministic();\n} catch (NonDeterministicException e) {\n  throw new IllegalStateException(\"Key coder must be deterministic: \" + e.getMessage());\n}","typeGuard":"boolean deterministicKey(Class<?> keyClass) { return !Double.class.equals(keyClass) && !Float.class.equals(keyClass); }","tryCatchPattern":"try {\n  coder.verifyDeterministic();\n} catch (NonDeterministicException e) {\n  // switch to quantized long key or deterministic custom coder\n}","preventionTips":["Never use raw double/float as GroupByKey keys; quantize to long or string.","Canonicalize NaN and -0.0 if floats must be keys.","Document determinism constraints in custom coder implementations."],"tags":["beam","java","coders","determinism"],"backgroundTag":"unsupported-operation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}