pentaho/pentaho-kettle · error · KettleException

KettleException( e )

Error message

KettleException( e )

What it means

ExcelWriterStep.closeOutputFile closes the underlying workbook (data.wb) and wraps any IOException in a bare KettleException. It means the generated Excel workbook could not be flushed/closed, so the output file may be incomplete or corrupt.

Solutions

  1. Check the wrapped IOException cause for disk/permission/lock details.
  2. Ensure the output file is not open in Excel or held by another process during the run.
  3. Verify free disk space and write permissions in the output directory.
  4. Write to a local temp file and move it to the final location after success.
  5. If writing to a network share, confirm the share is stable or write locally first.

Example fix

// before: closing workbook while file is locked
FileOutputStream fos = new FileOutputStream( lockedFile ); // Excel has it open
// after: verify writability and write atomically
File tmp = File.createTempFile( "out", ".xlsx", outputDir );
// write workbook to tmp, then:
Files.move( tmp.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING );
Defensive patterns

Strategy: try-catch

Validate before calling

File target = new File( outputPath );
if ( target.exists() && !target.canWrite() ) throw new IllegalStateException( "Output file locked: " + target );
if ( target.getFreeSpace() < minRequiredBytes ) throw new IllegalStateException( "Low disk space" );

Try / catch

try { workbook.close(); } catch ( IOException | KettleException e ) { logError( "Workbook close failed, output may be corrupt: " + e.getMessage(), e ); }

Prevention

When it happens

Trigger: closeOutputFile() calls data.wb.close() (or write()) and an IOException occurs — disk full, stream already closed, file locked by another process, or the underlying output stream failed.

Common situations: Target disk quota/full filesystem; the output file is open in Excel or another reader while the transformation writes; permission changes on the output directory; network drive disconnect during write of a large sheet.

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/cac58cc4c6e53437. Report an issue: GitHub.

Appendix: source

Thrown at plugins/excel/core/src/main/java/org/pentaho/di/trans/steps/excelwriter/ExcelWriterStep.java:299

        extendDataValidationRanges();
      }

      // force recalculation of formulas if requested
      if ( meta.isForceFormulaRecalculation() ) {
        recalculateAllWorkbookFormulas();
      }
      data.wb.write( out );
      if( data.wb instanceof SXSSFWorkbook ) {
        SXSSFWorkbook sxssfWorkbook = (SXSSFWorkbook) data.wb;
        sxssfWorkbook.dispose();
        sxssfWorkbook.close();
      }
      else {
        data.wb.close();
      }

    } catch ( IOException e ) {
      throw new KettleException( e );
    } finally {
      IOUtils.closeQuietly( data.wb );
      data.wb = null;
    }
  }

  private void extendDataValidationRanges() {
    DataValidationHelper helper = data.sheet.getDataValidationHelper();
    for ( DataValidation validation : data.sheet.getDataValidations() ) {
      CellRangeAddressList rangeList = validation.getRegions();
      // extend ranges that include data rows
      boolean updated = false;
      for ( CellRangeAddress range : rangeList.getCellRangeAddresses() ) {
        // extend any ranges that apply to the first data row but not the last
        if ( range.containsRow( data.startingRow ) && !range.containsRow( data.posY ) ) {
          range.setLastRow( data.posY );
          updated = true;
        }

View on GitHub (pinned to f3058517a1)