{"record":{"id":"0a9c17ab94a76c05","repo":"pentaho/pentaho-kettle","slug":"groupby-exception-unabletoreadbackrowfromtemporaryfile","errorCode":"GroupBy.Exception.UnableToReadBackRowFromTemporaryFile","errorMessage":"GroupBy.Exception.UnableToReadBackRowFromTemporaryFile","messagePattern":"GroupBy\\.Exception\\.UnableToReadBackRowFromTemporaryFile","errorType":"exception","errorClass":"KettleFileException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/groupby/GroupBy.java","lineNumber":823,"sourceCode":"  }\n\n  // Method is defined as public in order to be accessible by unit tests\n  public String retrieveVfsPath( String pathToTmp ) throws KettleFileException {\n    FileObject vfsFile = KettleVFS.getInstance( getTransMeta().getBowl() ).getFileObject( pathToTmp );\n    String path = vfsFile.getName().getPath();\n    return path;\n  }\n\n  private Object[] getRowFromBuffer() throws KettleFileException {\n    if ( data.rowsOnFile > 0 ) {\n      if ( data.firstRead ) {\n        // Open the inputstream first...\n        try {\n          data.fisToTmpFile = new FileInputStream( data.tempFile );\n          data.disToTmpFile = new DataInputStream( data.fisToTmpFile );\n          data.firstRead = false;\n        } catch ( IOException e ) {\n          throw new KettleFileException( BaseMessages.getString(\n              PKG, \"GroupBy.Exception.UnableToReadBackRowFromTemporaryFile\" ), e );\n        }\n      }\n\n      // Read one row from the file!\n      Object[] row;\n      try {\n        row = data.inputRowMeta.readData( data.disToTmpFile );\n      } catch ( SocketTimeoutException e ) {\n        throw new KettleFileException( e ); // Shouldn't happen on files\n      }\n      data.rowsOnFile--;\n\n      return row;\n    } else {\n      if ( data.bufferList.size() > 0 ) {\n        Object[] row = data.bufferList.get( 0 );\n        data.bufferList.remove( 0 );","sourceCodeStart":805,"sourceCodeEnd":841,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/groupby/GroupBy.java#L805-L841","documentation":"GroupBy buffered its rows to a temporary file when the group was too large for memory. This error wraps an IOException thrown while opening a FileInputStream/DataInputStream on that temp file to read rows back during getRowFromBuffer. It means the temp file that was just written is now unreadable.","triggerScenarios":"getRowFromBuffer opens data.tempFile via new FileInputStream(data.tempFile) after firstRead was set false by the writer; the file was deleted, the path is invalid, disk/permissions changed, or the stream was already consumed and reset failed.","commonSituations":"Temp directory cleaned by another process or tmpwatch mid-transformation; multiple transformation copies sharing data.tempFile; disk full or mount removed; running clustered where temp files aren't shared across nodes.","solutions":["Check that the java.io.tmpdir / Kettle temp directory exists, is writable, and is not purged while the transformation runs","Ensure the transformation isn't run in multiple copies/clustered mode such that copies overwrite each other's temp files","Verify sufficient disk space for the sorted group data","Call init() so data.tempFile is created before processRow; never construct the step data manually","Upgrade/patch: ensure closeOutput resets firstRead=true so a second pass re-opens the file cleanly"],"exampleFix":"// before\ntry {\n  data.fisToTmpFile = new FileInputStream( data.tempFile );\n// after\ntry {\n  if ( data.tempFile == null || !data.tempFile.exists() ) {\n    throw new KettleFileException( \"Temp file missing: \" + data.tempFile );\n  }\n  data.fisToTmpFile = new FileInputStream( data.tempFile );","handlingStrategy":"try-catch","validationCode":"// before running the transformation\nFile tmp = new File( System.getProperty( \"java.io.tmpdir\" ) );\nif ( !tmp.isDirectory() || !tmp.canWrite() ) throw new IllegalStateException( \"Temp dir not writable\" );\nif ( tmp.getUsableSpace() < 100L * 1024 * 1024 ) throw new IllegalStateException( \"Low temp disk space\" );","typeGuard":null,"tryCatchPattern":"try {\n  step.processRow();\n} catch ( KettleFileException e ) {\n  if ( e.getMessage().contains( \"UnableToReadBackRowFromTemporaryFile\" ) ) {\n    log.warn( \"GroupBy temp file unreadable; check {} for cleanup jobs\", System.getProperty( \"java.io.tmpdir\" ), e );\n  } else { throw e; }\n}","preventionTips":["Exclude Kettle temp dirs from OS cleanup daemons (tmpwatch, systemd-tmpfiles)","Use a dedicated local temp directory via KETTLE_SYSTEM_TMP_DIR env var","Monitor disk space on the temp volume before long transformations","Don't run transformations in multiple copies when using memory-limited GroupBy"],"tags":["kettle","pdi","file-io","groupby","temp-file"],"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"}