pentaho/pentaho-kettle · error · KettleException

KettleException( e )

Error message

KettleException( e )

What it means

Inside setFonts, after the header image is confirmed to exist, the step reads its bytes to build a WritableImage. Any exception during that sequence (getting content size, opening the VFS input stream, reading bytes) is rethrown as a bare KettleException with the original exception as cause.

Solutions

  1. Inspect the cause's stack trace — the wrapper message carries no detail of its own.
  2. Verify the header image is a readable, stable local file at execution time; copy it locally instead of reading from a network share.
  3. Check VFS connection settings (credentials, timeout) if the image lives on a remote filesystem.
  4. Ensure the file is not being modified/deleted concurrently between the exists() check and the read.
  5. Test opening the image with a plain FileInputStream from the PDI host to isolate VFS vs. image problems.

Example fix

// before: read without loop, assumes full read
imageStream.read( imageData );
// after: read fully and close properly
try ( InputStream in = KettleVFS.getInputStream( imageFile ) ) {
  int off = 0, n;
  while ( off < imageData.length && ( n = in.read( imageData, off, imageData.length - off ) ) >= 0 ) {
    off += n;
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

if ( !imageFile.exists() || imageFile.getContent().getSize() == 0 ) throw new KettleException( "Header image unreadable: " + imageFile.getName() );

Try / catch

try { /* image load */ } catch ( KettleException e ) { logError( "Image load failed: " + e.getCause(), e ); }

Prevention

When it happens

Trigger: setFonts() (called from openNewFile()) fails at imageFile.getContent().getSize(), KettleVFS.getInputStream(imageFile), or imageStream.read(imageData) — e.g. VFS provider errors, size change between size query and read, or IO failure on the image file.

Common situations: Image on a network/SFTP share that drops mid-read; file truncated or locked by another process; VFS authentication failure when fetching the stream; image larger than memory assumptions; race where the file is deleted between the exists() check and the read.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

Appendix: source

Thrown at plugins/excel/core/src/main/java/org/pentaho/di/trans/steps/exceloutput/ExcelOutput.java:826

      InputStream imageStream = null;
      try ( FileObject imageFile = KettleVFS.getInstance( getTransMeta().getBowl() )
              .getFileObject( data.realHeaderImage ) ) {
        if ( !imageFile.exists() ) {
          throw new KettleException( BaseMessages.getString( PKG, "ExcelInputLog.ImageFileNotExists", data.realHeaderImage ) );
        }
        data.realHeaderImage = KettleVFS.getFilename( imageFile );
        // Put an image
        Dimension m = ExcelFontMap.getImageDimension( data.realHeaderImage );
        data.headerImageWidth = m.getWidth() * 0.016;
        data.headerImageHeight = m.getHeight() * 0.0625;

        byte[] imageData = new byte[(int) imageFile.getContent().getSize()];
        imageStream = KettleVFS.getInputStream( imageFile );
        imageStream.read( imageData );

        data.headerImage = new WritableImage( 0, 0, data.headerImageWidth, data.headerImageHeight, imageData );
      } catch ( Exception e ) {
        throw new KettleException( e );
      }
    }

    // --- Set rows font
    // Set font size
    int rowFontSize = Const.toInt( environmentSubstitute( meta.getRowFontSize() ), ExcelOutputMeta.DEFAULT_FONT_SIZE );
    // Set font name
    FontName rowFontName = ExcelFontMap.getFontName( meta.getRowFontName() );

    data.writableFont = new WritableFont( rowFontName, rowFontSize, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE );

    // Row font color
    Colour rowFontColour = ExcelFontMap.getColour( meta.getRowFontColor(), Colour.BLACK );
    if ( !fontHeaderColour.equals( Colour.BLACK ) ) {
      data.writableFont.setColour( rowFontColour );
    }

    // Set rows background color if needed

View on GitHub (pinned to f3058517a1)