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
- Inspect the cause's stack trace — the wrapper message carries no detail of its own.
- Verify the header image is a readable, stable local file at execution time; copy it locally instead of reading from a network share.
- Check VFS connection settings (credentials, timeout) if the image lives on a remote filesystem.
- Ensure the file is not being modified/deleted concurrently between the exists() check and the read.
- 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
- Keep header images on local, stable storage rather than network shares.
- Copy the image before reading to avoid concurrent modification.
- Confirm the image is a valid, non-empty file before configuring it.
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
- KettleException( e )
- ExcelInputLog.ImageFileNotExists
- The function call getShortFilename throw an error : +…
- The function call isFolder throw an error : + e.toString()
- Unable to add filename to the result
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 neededView on GitHub (pinned to f3058517a1)