pentaho/pentaho-kettle · error · KettleException

IO exception occured:

Error message

IO exception occured: 

What it means

OraBulkDataOutput.open creates the data file for the Oracle SQL*Loader and wraps it in a BufferedWriter. If creating or wrapping the output stream throws an IOException, it is rethrown as a KettleException 'IO exception occured: <message>'. It means the loader could not open/write its staging data file.

Solutions

  1. Check the chained IOException message for the exact filesystem reason (No such file, Permission denied, No space left)
  2. Verify the directory the data file is written to exists and is writable by the PDI user
  3. Free disk space or point the loader's file/directory setting at a valid writable location
Defensive patterns

Strategy: try-catch

Validate before calling

File dir = new File( outputDir );
if ( !dir.isDirectory() || !dir.canWrite() ) {
  throw new KettleException( "Output dir not writable: " + outputDir );
}

Try / catch

try {
  oraOutput.open();
} catch ( KettleException e ) {
  logError( "Cannot open data file: " + e.getMessage(), e );
}

Prevention

When it happens

Trigger: open() is called and new FileOutputStream/OutputStreamWriter fails: bad file path, no write permission, disk full, or directory does not exist.

Common situations: Invalid temp/data directory configured for the loader; read-only mount or missing directory; disk quota exceeded on the server running PDI; filename containing illegal characters for the OS.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/a0c2a0e6b488885b. Report an issue: GitHub.

Appendix: source

Thrown at plugins/oracle-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/orabulkloader/OraBulkDataOutput.java:91

      } else {
        // Else open the data file filled in.
        String dataFilePath = getFilename( getFileObject( bowl, space.environmentSubstitute( meta.getDataFile() ), space ) );
        File dataFile = new File( dataFilePath );
        // Make sure the parent directory exists
        dataFile.getParentFile().mkdirs();
        os = new FileOutputStream( dataFile, false );
      }

      String encoding = meta.getEncoding();
      if ( Utils.isEmpty( encoding ) ) {
        // Use the default encoding.
        output = new BufferedWriter( new OutputStreamWriter( os ) );
      } else {
        // Use the specified encoding
        output = new BufferedWriter( new OutputStreamWriter( os, encoding ) );
      }
    } catch ( IOException e ) {
      throw new KettleException( "IO exception occured: " + e.getMessage(), e );
    }
  }

  public void close() throws IOException {
    if ( output != null ) {
      output.close();
    }
  }

  Writer getOutput() {
    return output;
  }

  private String createEscapedString( String orig, String enclosure ) {
    StringBuilder buf = new StringBuilder( orig );

    Const.repl( buf, enclosure, enclosure + enclosure );
    return buf.toString();

View on GitHub (pinned to f3058517a1)