{"record":{"id":"59e982a464e44133","repo":"pentaho/pentaho-kettle","slug":"groupby-exception-unabletocloseinputstream","errorCode":"GroupBy.Exception.UnableToCloseInputStream","errorMessage":"GroupBy.Exception.UnableToCloseInputStream","messagePattern":"GroupBy\\.Exception\\.UnableToCloseInputStream","errorType":"exception","errorClass":"KettleFileException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/groupby/GroupBy.java","lineNumber":861,"sourceCode":"      } else {\n        return null; // Nothing left!\n      }\n    }\n  }\n\n  private void closeOutput() throws KettleFileException {\n    try {\n      if ( data.dosToTempFile != null ) {\n        data.dosToTempFile.close();\n        data.dosToTempFile = null;\n      }\n      if ( data.fosToTempFile != null ) {\n        data.fosToTempFile.close();\n        data.fosToTempFile = null;\n      }\n      data.firstRead = true;\n    } catch ( IOException e ) {\n      throw new KettleFileException(\n          BaseMessages.getString( PKG, \"GroupBy.Exception.UnableToCloseInputStream\", data.tempFile.getPath() ), e );\n    }\n  }\n\n  private void closeInput() throws KettleFileException {\n    try {\n      if ( data.fisToTmpFile != null ) {\n        data.fisToTmpFile.close();\n        data.fisToTmpFile = null;\n      }\n      if ( data.disToTmpFile != null ) {\n        data.disToTmpFile.close();\n        data.disToTmpFile = null;\n      }\n    } catch ( IOException e ) {\n      throw new KettleFileException(\n          BaseMessages.getString( PKG, \"GroupBy.Exception.UnableToCloseInputStream\", data.tempFile.getPath() ), e );\n    }","sourceCodeStart":843,"sourceCodeEnd":879,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/groupby/GroupBy.java#L843-L879","documentation":"GroupBy throws this KettleFileException from closeOutput when the FileOutputStream used to buffer group rows to a temporary file cannot be closed without an IOException. It signals the temp file write-side cleanup failed, typically due to an underlying disk or stream problem.","triggerScenarios":"processRow or dispose calls closeOutput(); data.fosToTmpFile.close() (or the wrapped buffered stream) throws IOException because the temp file handle is broken, the disk is full, or the stream was already closed.","commonSituations":"Disk full while flushing the last buffer; NFS/Windows file-lock issues on the temp file; double-dispose racing on the same stream; OS-level file descriptor exhaustion.","solutions":["Check disk space on the temp filesystem used by data.tempFile","Avoid running dispose() twice on the same step data; ensure single lifecycle per transformation copy","Close streams in a finally block only once; set references to null after closing (code already does)","Inspect the wrapped IOException cause for the root OS error","If on network storage, switch java.io.tmpdir to local disk"],"exampleFix":"// before\n} catch ( IOException e ) {\n  throw new KettleFileException(\n    BaseMessages.getString( PKG, \"GroupBy.Exception.UnableToCloseInputStream\", data.tempFile.getPath() ), e );\n// after\n} catch ( IOException e ) {\n  if ( data.fosToTempFile != null ) { try { data.fosToTempFile.close(); } catch ( IOException ignore ) {} }\n  throw new KettleFileException(\n    BaseMessages.getString( PKG, \"GroupBy.Exception.UnableToCloseInputStream\", data.tempFile.getPath() ), e );","handlingStrategy":"try-catch","validationCode":"// preflight disk space on temp volume\nif ( new File( System.getProperty( \"java.io.tmpdir\" ) ).getUsableSpace() < 256L * 1024 * 1024 ) {\n  throw new IllegalStateException( \"Insufficient temp disk space for GroupBy spool\" );\n}","typeGuard":null,"tryCatchPattern":"try {\n  transformation.execute( arguments );\n} catch ( KettleException e ) {\n  if ( e.getMessage().contains( \"UnableToCloseInputStream\" ) ) {\n    log.error( \"GroupBy temp-file stream close failed; check disk and file locks\", e );\n  } else { throw e; }\n}","preventionTips":["Ensure ample free disk space for spooled group data","Keep temp files on local disk, not NFS/SMB shares","Avoid concurrent dispose/restart of the same step data","Check the wrapped IOException cause for the real OS error"],"tags":["kettle","pdi","file-io","groupby","stream-close"],"backgroundTag":"file-write-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"}