{"record":{"id":"5a6b2aabb8c98724","repo":"pentaho/pentaho-kettle","slug":"groupby-exception-unabletocreatetemporaryfile","errorCode":"GroupBy.Exception.UnableToCreateTemporaryFile","errorMessage":"GroupBy.Exception.UnableToCreateTemporaryFile","messagePattern":"GroupBy\\.Exception\\.UnableToCreateTemporaryFile","errorType":"exception","errorClass":"KettleFileException","httpStatus":null,"severity":"critical","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/groupby/GroupBy.java","lineNumber":796,"sourceCode":"  }\n\n  // Method is defined as package-protected in order to be accessible by unit tests\n  void addToBuffer( Object[] row ) throws KettleFileException {\n    data.bufferList.add( row );\n    if ( data.bufferList.size() > 5000 && data.rowsOnFile == 0 ) {\n      String pathToTmp = environmentSubstitute( getMeta().getDirectory() );\n      try {\n        File ioFile = new File( pathToTmp );\n        if ( !ioFile.exists() ) {\n          // try to resolve as Apache VFS file\n          pathToTmp = retrieveVfsPath( pathToTmp );\n        }\n        data.tempFile = File.createTempFile( getMeta().getPrefix(), \".tmp\", new File( pathToTmp ) );\n        data.fosToTempFile = new FileOutputStream( data.tempFile );\n        data.dosToTempFile = new DataOutputStream( data.fosToTempFile );\n        data.firstRead = true;\n      } catch ( IOException e ) {\n        throw new KettleFileException( BaseMessages.getString( PKG, \"GroupBy.Exception.UnableToCreateTemporaryFile\" ),\n            e );\n      }\n      // OK, save the oldest rows to disk!\n      Object[] oldest = data.bufferList.get( 0 );\n      data.inputRowMeta.writeData( data.dosToTempFile, oldest );\n      data.bufferList.remove( 0 );\n      data.rowsOnFile++;\n    }\n  }\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 {","sourceCodeStart":778,"sourceCodeEnd":814,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/groupby/GroupBy.java#L778-L814","documentation":"When GroupBy's row buffer exceeds its size and sorting is enabled, addToBuffer spills the oldest rows to a temporary file. File.createTempFile / FileOutputStream creation failures are wrapped in a KettleFileException with this localized message. It means the step could not create or open its spill temp file, so grouping cannot continue.","triggerScenarios":"addToBuffer calls File.createTempFile(prefix, \".tmp\", new File(pathToTmp)) and an IOException occurs: java.io.tmpdir (or the configured temp directory) doesn't exist, is read-only, is full, or the OS denies file creation for the running user.","commonSituations":"Disk full on /tmp after long-running transformations; tmp dir cleaned by a cron job while the transformation runs; Kettle's internal.tmpdir setting pointing to a nonexistent path; container running with a read-only filesystem or tiny tmpfs.","solutions":["Free disk space in the temp directory (or point java.io.tmpdir / Kettle 'java.io.tmpdir' option to a volume with room).","Verify the configured temp path exists and is writable by the user running Pentaho/Kettle.","In Spoon, set the transformation's temp directory or start Kettle with -Djava.io.tmpdir=/path/writable.","Increase the sort/group buffer size so less spilling occurs, or reduce input size.","In containers, mount a writable tmp volume instead of relying on a read-only overlay."],"exampleFix":"// before: default tmpdir full or read-only\njava -jar pentaho-kettle.jar\n// after\njava -Djava.io.tmpdir=/data/kettle-tmp -jar pentaho-kettle.jar\n# with: mkdir -p /data/kettle-tmp && chmod 770 /data/kettle-tmp","handlingStrategy":"validation","validationCode":"String tmp = System.getProperty( \"java.io.tmpdir\" );\nFile dir = new File( tmp );\nif ( !dir.isDirectory() || !dir.canWrite() || dir.getUsableSpace() < 512L * 1024 * 1024 ) {\n  throw new IllegalStateException( \"Temp dir unusable or low on space: \" + tmp );\n}","typeGuard":null,"tryCatchPattern":"try {\n  trans.execute( null );\n} catch ( KettleFileException e ) {\n  if ( e.getMessage().contains( \"UnableToCreateTemporaryFile\" ) ) {\n    logError( \"Temp dir full/unwritable - free space or set -Djava.io.tmpdir\" );\n  }\n}","preventionTips":["Monitor disk space on the temp volume for long-running transformations.","Point java.io.tmpdir to a dedicated, writable, adequately-sized directory.","Exclude Kettle tmp dirs from aggressive cleanup cron jobs.","Mount a writable tmp volume in containerized deployments."],"tags":["kettle","temp-file","filesystem","io","disk-space"],"backgroundTag":"file-open-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"}