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
- Verify the sender completed writeMeta successfully — check for paired write-side exceptions or partial sends.
- Re-request the metadata over a fresh connection; partial metadata is unusable.
- Check PDI version compatibility between sender and receiver so field serialization layouts match.
- 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
- Check sender-side write completion; partial sends corrupt the protocol.
- Keep PDI versions aligned so field layouts match.
- Frame messages with lengths so truncation is detected immediately.
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
- End of file reached
- End of file reached while reading value
- End of file while reading the number of metadata values in…
- End of file reached
- Error reading from data input stream
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)