{"record":{"id":"2d8d07052e7102fe","repo":"pentaho/pentaho-kettle","slug":"end-of-file-reached","errorCode":null,"errorMessage":"End of file reached","messagePattern":"End of file reached","errorType":"exception","errorClass":"KettleEOFException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/compatibility/Value.java","lineNumber":1639,"sourceCode":"        default:\n          break;\n      }\n    }\n  }\n\n  /**\n   * Read the Value, including meta-data from a DataInputStream\n   *\n   * @param is\n   *          The InputStream to read the value from\n   * @throws KettleFileException\n   *           when the Value couldn't be created by reading it from the DataInputStream.\n   */\n  public Value( InputStream is ) throws KettleFileException {\n    try {\n      readObj( new DataInputStream( is ) );\n    } catch ( EOFException e ) {\n      throw new KettleEOFException( \"End of file reached\", e );\n    } catch ( Exception e ) {\n      throw new KettleFileException( \"Error reading from data input stream\", e );\n    }\n  }\n\n  /**\n   * Write the data of this Value, without the meta-data to a DataOutputStream\n   *\n   * @param dos\n   *          The DataOutputStream to write the data to\n   * @return true if all went well, false if something went wrong.\n   */\n  public boolean writeData( DataOutputStream dos ) throws KettleFileException {\n    try {\n      // Is the value NULL?\n      dos.writeBoolean( isNull() );\n\n      // Handle Content -- only when not NULL","sourceCodeStart":1621,"sourceCodeEnd":1657,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/compatibility/Value.java#L1621-L1657","documentation":"This KettleEOFException is thrown by the Value(InputStream) constructor when readObj() hits an EOFException while deserializing a Value from a DataInputStream. It means the underlying stream ended before the complete serialized value could be read, i.e. truncated or exhausted data. The library throws it to distinguish 'stream ended prematurely' from other deserialization failures, which surface as KettleFileException instead.","triggerScenarios":"Constructing new Value( InputStream ) (or code paths that deserialize Value rows from files/sockets) when the stream has fewer bytes than the serialized value requires: truncated kettle .ktr/.kjb data files, a socket/pipe closed mid-record, or reading past the last record of a file.","commonSituations":"Reading a partially-downloaded or partially-written Kettle serialized file; a producer process crashed mid-write; using an InputStream that was already fully consumed by a previous reader; HDFS/FTP transfer size mismatches; incorrect row-count assumptions when streaming value sequences.","solutions":["Verify the source file/stream is complete and uncorrupted (check file size vs. expected size, re-download or re-export).","Ensure the writer finished and flushed/closed the stream before the reader starts (or retry after the producer completes).","Wrap the reading loop in a check for stream availability before constructing Value, or use the Kettle row-input APIs (e.g. RowMeta.getRow) which handle EOF signaling gracefully.","Upgrade/align PDI versions on writer and reader — serialization format mismatches can cause premature EOF.","Catch KettleEOFException explicitly and treat it as a normal end-of-input signal if reading a sequence of values."],"exampleFix":"// before\nValue v = new Value( inputStream ); // throws KettleEOFException on truncated stream\n// after\ntry {\n  Value v = new Value( inputStream );\n} catch ( KettleEOFException e ) {\n  // end of stream: treat as end-of-input or flag truncation\n  logger.warn( \"Truncated value stream at byte offset \" + bytesRead, e );\n  return;\n}","handlingStrategy":"try-catch","validationCode":"// before reading\nif ( !inputStreamAvailable( in ) ) {\n  throw new IllegalStateException( \"Stream already exhausted; cannot read Value\" );\n}\nprivate boolean inputStreamAvailable( InputStream in ) throws IOException {\n  if ( in instanceof BufferedInputStream ) return true; // cannot peek generic streams safely\n  return in.available() > 0 || in.read() != -1;\n}","typeGuard":"// ensure the stream is a known-size, complete source\nboolean isCompleteSource( File f, long expectedBytes ) {\n  return f.isFile() && f.length() == expectedBytes;\n}","tryCatchPattern":"try {\n  Value v = new Value( in );\n} catch ( KettleEOFException e ) {\n  // end-of-input or truncation: stop reading, verify completeness\n  handleEndOfStream( e );\n}","preventionTips":["Always verify producer completion (file finalization, checksum) before reading serialized data.","Use Kettle's row-level input APIs that signal EOF instead of raw Value construction.","Keep writer and reader PDI versions aligned.","Retry truncated transfers automatically and compare byte counts.","Treat KettleEOFException as end-of-data, not as a retryable fault."],"tags":["io","deserialization","streaming","eof"],"backgroundTag":"file-read-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}