pentaho/pentaho-kettle · error · org.pentaho.di.core.exception.KettleEOFException

KettleEOFException wrapping EOFException (no message)

Error message

KettleEOFException wrapping EOFException (no message)

What it means

Inside the RowMeta(InputStream) constructor loop, each field's type int is read and a value meta created. An EOFException while reading a field's type means the stream ended partway through the metadata — some fields were read but the remaining ones are missing. It is rethrown as a message-less KettleEOFException carrying the EOFException as cause.

Solutions

  1. Verify the sender completed writeMeta successfully — check for paired write-side exceptions or partial sends.
  2. Re-request the metadata over a fresh connection; partial metadata is unusable.
  3. Check PDI version compatibility between sender and receiver so field serialization layouts match.
  4. If reading a file, detect truncation (size vs expected length) and regenerate it.

Example fix

// before
RowMeta rowMeta = new RowMeta(inputStream); // KettleEOFException mid-fields
// after
try {
  RowMeta rowMeta = new RowMeta(inputStream);
} catch (KettleEOFException e) {
  log.error("Metadata stream truncated after some fields", e);
  inputStream = reconnect();
  RowMeta rowMeta = new RowMeta(inputStream);
}
Defensive patterns

Strategy: retry

Validate before calling

int expectedBytes = 4 * nrFieldsDeclaredBySender;
if (inputStream.available() < expectedBytes) { throw new KettleException("Insufficient bytes for declared fields"); }

Try / catch

try {
  RowMeta rowMeta = new RowMeta(inputStream);
} catch (KettleEOFException e) {
  log.error("Stream ended mid-metadata", e);
  inputStream = reconnect();
  RowMeta rowMeta = new RowMeta(inputStream);
}

Prevention

When it happens

Trigger: Deserializing metadata where the declared field count (nr) exceeds the bytes actually available: sender wrote the header but died before writing all field types; truncated file; peer connection dropped mid-message.

Common situations: Network partitions during PDI cluster metadata exchange; partially-written cache files; version mismatch where the receiver misinterprets the sender's serialization format and runs out of bytes early.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/b7c91398b1ae993b. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/row/RowMeta.java:740

    try {
      nr = inputStream.readInt();
    } catch ( SocketTimeoutException e ) {
      throw e;
    } catch ( EOFException e ) {
      throw new KettleEOFException(
        "End of file while reading the number of metadata values in the row metadata", e );
    } catch ( IOException e ) {
      throw new KettleFileException( "Unable to read nr of metadata values: " + e.toString(), e );
    }

    for ( int i = 0; i < nr; i++ ) {
      try {
        int type = inputStream.readInt();
        ValueMetaInterface valueMeta = ValueMetaFactory.createValueMeta( type );
        valueMeta.readMetaData( inputStream );
        addValueMeta( valueMeta );
      } catch ( EOFException e ) {
        throw new KettleEOFException( e );
      } catch ( Exception e ) {
        throw new KettleFileException( toString() + " : Unable to read row metadata from input stream", e );
      }

    }
  }

  @Override
  public Object[] readData( DataInputStream inputStream ) throws KettleFileException, SocketTimeoutException {
    lock.readLock().lock();
    try {
      Object[] data = new Object[ size() ];
      for ( int i = 0; i < size(); i++ ) {
        data[ i ] = getValueMeta( i ).readData( inputStream );
      }
      if ( size() == 0 ) {
        try {
          inputStream.readBoolean();

View on GitHub (pinned to f3058517a1)