apache/hadoop · error · IOException

Malformed varint

Error message

Malformed varint

What it means

ProtoUtil.readRawVarint32() decodes a protobuf base-128 varint from a DataInput, as used in Hadoop RPC handshakes and length-prefixed protobuf frames. A 32-bit varint needs at most 5 bytes, and up to 5 further continuation bytes of a 64-bit encoding are discarded; if after those the stream still has the continuation bit set (byte < 0), the encoding is invalid and it throws IOException("Malformed varint").

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ProtoUtil.java:73

    } else {
      result |= (tmp & 0x7f) << 7;
      if ((tmp = in.readByte()) >= 0) {
        result |= tmp << 14;
      } else {
        result |= (tmp & 0x7f) << 14;
        if ((tmp = in.readByte()) >= 0) {
          result |= tmp << 21;
        } else {
          result |= (tmp & 0x7f) << 21;
          result |= (tmp = in.readByte()) << 28;
          if (tmp < 0) {
            // Discard upper 32 bits.
            for (int i = 0; i < 5; i++) {
              if (in.readByte() >= 0) {
                return result;
              }
            }
            throw new IOException("Malformed varint");
          }
        }
      }
    }
    return result;
  }

  
  /** 
   * This method creates the connection context  using exactly the same logic
   * as the old connection context as was done for writable where
   * the effective and real users are set based on the auth method.
   *
   * @param protocol protocol.
   * @param ugi ugi.
   * @param authMethod authMethod.
   * @return IpcConnectionContextProto.
   */

View on GitHub (pinned to 2add963021)

Solutions

  1. Verify both ends run compatible Hadoop/RPC protocol versions
  2. Instrument the writer, not just the reader — confirm every length is written with the matching varint encoding (protobuf CodedOutputStream / DataOutputByteBuffer paths)
  3. On this IOException, drop the connection/session; do not attempt to resynchronize mid-stream
  4. For custom protocols, write with writeRawVarint32-style encoding and pair it with this reader

Example fix

// before: writer emits a fixed 4-byte length, reader expects varint
dout.writeInt(len);

// after: matching varint encoding on both sides
// writer
org.apache.hadoop.ipc.protobuf.RpcHeaderProtosHelper.writeRawVarint32(dout, len);
// reader
int len = ProtoUtil.readRawVarint32(din);
Defensive patterns

Strategy: try-catch

Try / catch

try { len = ProtoUtil.readRawVarint32(in); } catch (IOException e) { // "Malformed varint" => stream is desynced; never resync mid-stream
  throw new IOException("RPC stream corrupted (malformed varint); closing connection", e); }

Prevention

When it happens

Trigger: Feeding readRawVarint32 a stream that is not positioned at a varint: RPC frame desync after an earlier field was misread; client and server Hadoop versions disagreeing on wire serialization; bytes corrupted or mangled by SASL/QOP or a middlebox; custom code reusing the helper on arbitrary buffers.

Common situations: Mixed Hadoop client/server versions on one cluster; hand-rolled RPC clients writing lengths as fixed ints or strings; tests writing raw payloads where a varint length is expected; proxies altering the byte stream.

Understand the failure class

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/922c26779f660a3a. Report an issue: GitHub.