apache/beam · error · CoderException

Could not transport value. Error

Error message

Could not transport value. Error: %s

What it means

ThriftCoder serializes TBase Thrift objects to a stream via a Thrift protocol/transport. When the underlying TTransportException occurs during writing (broken transport, closed stream, protocol errors), encode wraps it in a CoderException with the transport message. It signals the Thrift serialization itself failed at the transport layer, distinct from the generic write failure branch.

Solutions

  1. Inspect the CoderException message (the original TTransportException text) and the underlying cause to identify the transport failure.
  2. Ensure the OutputStream passed to encode is open and writable for the duration of serialization.
  3. Match the protocolFactory to how the data will be read (TTupleProtocol/TBinaryProtocol/TCompactProtocol consistency between encode and decode).
  4. Retry the write; if transient stream breakage in a pipeline, rely on Beam's retry semantics rather than swallowing.

Example fix

// before
Coder<MyEvent> coder = ThriftCoder.of(MyEvent.class); // mismatched protocol vs reader
// after — ensure same protocol factory used by both encoder and decoder
Coder<MyEvent> coder = ThriftCoder.of(
    new TSerializer(new TCompactProtocol.Factory()),
    new TDeserializer(new TCompactProtocol.Factory()),
    MyEvent.class);
Defensive patterns

Strategy: try-catch

Validate before calling

// Java — validate the value is a TBase before encoding
if (!(value instanceof TBase)) {
  throw new IllegalArgumentException("ThriftCoder only encodes TBase instances");
}

Type guard

boolean encodable(Object v) { return v instanceof TBase; }

Try / catch

try {
  coder.encode(event, outStream);
} catch (CoderException e) {
  // transport-level Thrift failure: inspect message/cause, check stream state and protocol factory match
  LOG.error("Thrift transport failure while encoding: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling Beam's ThriftIO or using ThriftCoder directly to encode a TBase object when the TIOStreamTransport's underlying OutputStream throws, the protocol write exceeds transport limits, or serialization hits a TTransportException (e.g., end of stream, transport closed).

Common situations: Encoding during a sink write where the output stream was closed early (e.g., worker shutdown, channel break); encoding very large Thrift structs; malformed generated Thrift classes (wrong protocol factory — e.g., binary protocol vs compact) causing transport-level failures.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


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

Appendix: source

Thrown at sdks/java/io/thrift/src/main/java/org/apache/beam/sdk/io/thrift/ThriftCoder.java:79

    return new ThriftCoder<>(clazz, protocolFactory);
  }

  /**
   * Encodes the given value of type {@code T} onto the given output stream using provided {@link
   * ThriftCoder#protocolFactory}.
   *
   * @param value {@link org.apache.thrift.TBase} to encode.
   * @param outStream stream to output encoded value to.
   * @throws IOException if writing to the {@code OutputStream} fails for some reason
   */
  @Override
  public void encode(T value, OutputStream outStream) throws CoderException, IOException {
    try {
      TProtocol protocol = protocolFactory.getProtocol(new TIOStreamTransport(outStream));
      TBase<?, ?> tBase = (TBase<?, ?>) value;
      tBase.write(protocol);
    } catch (TTransportException tte) {
      throw new CoderException("Could not transport value. Error: " + tte.getMessage());
    } catch (Exception te) {
      throw new CoderException("Could not write value. Error: " + te.getMessage());
    }
  }

  /**
   * Decodes a value of type {@code T} from the given input stream using provided {@link
   * ThriftCoder#protocolFactory}. Returns the decoded value.
   *
   * @param inStream stream of input values to be decoded
   * @throws IOException if reading from the {@code InputStream} fails for some reason
   * @throws CoderException if the value could not be decoded for some reason
   * @return {@link TBase} decoded object
   */
  @Override
  public T decode(InputStream inStream) throws CoderException, IOException {
    try {
      TProtocol protocol = protocolFactory.getProtocol(new TIOStreamTransport(inStream));

View on GitHub (pinned to 12126d8942)