pentaho/pentaho-kettle · error · KettleException

KettleException( e )

Error message

KettleException( e )

What it means

The catch-all branch of PoiWorkbook's filename constructor wraps any non-encryption Exception from opening the workbook (invalid file, wrong format, IOUtils byte-array limit exceeded, corrupt ZIP) in a KettleException with the original as cause. It is the generic 'could not load this workbook' failure.

Solutions

  1. Verify the file exists, is readable, and is a genuine xls/xlsx (check with `file` command).
  2. Inspect e.getCause(); if it mentions a byte-array max, increase the maxSize configuration.
  3. Select the correct reader (ODS vs POI) for the actual file format.
  4. Re-save/export the workbook from Excel to repair structural corruption.

Example fix

// before
Workbook wb = new PoiWorkbook(bowl, filename, password, encoding, log);
// after
if (!filename.endsWith(".xls") && !filename.endsWith(".xlsx"))
  throw new KettleException("Expected xls/xlsx, got: " + filename);
Workbook wb = new PoiWorkbook(bowl, filename, password, encoding, log);
Defensive patterns

Strategy: validation

Validate before calling

File f = new File(filename);
if (!f.exists() || !f.canRead()) throw new KettleException("Cannot read: " + filename);
try (FileInputStream in = new FileInputStream(f)) {
  byte[] hdr = new byte[4]; in.read(hdr);
  boolean xls = hdr[0]=='D'&&hdr[1]=='C'; boolean xlsx = hdr[0]=='P'&&hdr[1]=='K';
  if (!xls && !xlsx) throw new KettleException("Not an xls/xlsx file: " + filename);
}

Try / catch

try { wb = new PoiWorkbook(bowl, filename, password, encoding, log); } catch (KettleException e) { throw new KettleException("Open failed for '" + filename + "'; cause: " + e.getCause(), e); }

Prevention

When it happens

Trigger: new PoiWorkbook(bowl, filename, password, encoding, log) when WorkbookFactory.create or KettleVFS.getInputStream throws anything other than EncryptedDocumentException: FileNotFound, InvalidFormatException, IOException, POI's IOUtils limit breach.

Common situations: Pointing the step at an .ods, .csv, or HTML file mislabeled as .xlsx; file locked or unreadable by the service account; very large workbooks exceeding POI's default byte-array max override configured via maxSize.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at plugins/excel/core/src/main/java/org/pentaho/di/trans/steps/excelinput/poi/PoiWorkbook.java:89

            opcpkg = OPCPackage.open( excelFile );
            workbook = XSSFWorkbookFactory.createWorkbook( opcpkg );
          } catch ( Exception ex ) {
            workbook = org.apache.poi.ss.usermodel.WorkbookFactory.create( excelFile, password );
          }
        }
      } else {
          //default value for maximum allowed size we are maintaining 150MB  150 * 1024 * 1024
          int maxSize = Const.toInt( EnvUtil.getSystemProperty( Const.POI_BYTE_ARRAY_MAX_SIZE ), 157286400 );
          // Increase the maximum allowed size
          org.apache.poi.util.IOUtils.setByteArrayMaxOverride( maxSize );
          internalIS = KettleVFS.getInstance( bowl ).getInputStream( filename );
          workbook = org.apache.poi.ss.usermodel.WorkbookFactory.create( internalIS, password );
      }
    } catch ( EncryptedDocumentException e ) {
      log.logError( "Unable to open spreadsheet.  If the spreadsheet is password protected please double check the password is correct." );
      throw new KettleException( e.getLocalizedMessage() );
    } catch ( Exception e ) {
      throw new KettleException( e );
    }
  }

  public PoiWorkbook( InputStream inputStream, String encoding ) throws KettleException {
    this.encoding = encoding;

    try {
      workbook = org.apache.poi.ss.usermodel.WorkbookFactory.create( inputStream );
    } catch ( Exception e ) {
      throw new KettleException( e );
    }
  }

  public void close() {
    try {
      if ( internalIS != null ) {
        internalIS.close();
      }

View on GitHub (pinned to f3058517a1)