apache/beam · error · EOFException

EOF encountered decoding 1 byte from input stream

Error message

EOF encountered decoding 1 byte from input stream

What it means

ByteCoder.decode throws EOFException when inStream.read() returns -1, i.e. the stream ended before the 1 byte needed to decode a Byte was available. This indicates truncated, empty, or misaligned encoded input.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/coders/ByteCoder.java:55

  private static final TypeDescriptor<Byte> TYPE_DESCRIPTOR = new TypeDescriptor<Byte>() {};

  private ByteCoder() {}

  @Override
  public void encode(Byte value, OutputStream outStream) throws IOException, CoderException {
    if (value == null) {
      throw new CoderException("cannot encode a null Byte");
    }
    outStream.write(value);
  }

  @Override
  public Byte decode(InputStream inStream) throws IOException, CoderException {
    try {
      // value will be between 0-255, -1 for EOF
      int value = inStream.read();
      if (value == -1) {
        throw new EOFException("EOF encountered decoding 1 byte from input stream");
      }
      return (byte) value;
    } catch (EOFException | UTFDataFormatException exn) {
      // These exceptions correspond to decoding problems, so change
      // what kind of exception they're branded as.
      throw new CoderException(exn);
    }
  }

  /**
   * {@inheritDoc}
   *
   * <p>{@link ByteCoder} will never throw a {@link Coder.NonDeterministicException}; bytes can
   * always be encoded deterministically.
   */
  @Override
  public void verifyDeterministic() {}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Check stream availability / remaining length before calling decode
  2. Fix the framing loop so it stops at exactly the number of encoded elements written
  3. Catch EOFException/CoderException and treat it as end-of-data if legitimate
  4. Regenerate or re-fetch the truncated input data

Example fix

// before
while (true) { out.add(coder.decode(in)); }
// after
while (in.available() > 0) {
  try {
    out.add(coder.decode(in));
  } catch (CoderException | EOFException e) {
    break; // clean end of data
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (inStream.available() < 1) { throw new IllegalStateException("stream exhausted before Byte decode"); }

Try / catch

try { Byte b = ByteCoder.of().decode(in); } catch (CoderException | EOFException e) { /* truncated input: stop loop or dead-letter */ }

Prevention

When it happens

Trigger: Decoding from an exhausted stream (empty file, truncated record, wrong offset), or a framing loop that attempts one more decode after the last encoded element.

Common situations: Reading past the last element in length-prefixed data, byte-count errors in custom framing, network streams cut short, closed/finished streams.

Related errors


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