pentaho/pentaho-kettle · error · KettleException

ExcelInputLog.ImageFileNotExists

ExcelInputLog.ImageFileNotExists

Error message

ExcelInputLog.ImageFileNotExists (localized message with image path)

What it means

When the ExcelOutput step is configured with a header image, setFonts resolves the image via KettleVFS and throws this localized KettleException if the file does not exist. The message embeds the configured image path so the user can see exactly which file was missing.

Solutions

  1. Check the 'Header image' field in the Excel Output step dialog and correct the path (the error message shows the exact path used).
  2. Use an absolute path or a path relative to the transformation's working directory, and verify the file exists at runtime (ls / stat).
  3. If the path uses ${VARIABLES}, confirm they are set in the execution environment and substitute to an existing file.
  4. Copy the image to a location readable by the PDI process user (permissions can make exists() false for inaccessible paths on some VFS providers).
  5. Clear the header image setting if the image is optional and its absence should not abort the transformation.

Example fix

// before: relative path that may resolve incorrectly
String img = "images/logo.png";
// after: resolve explicitly and verify
File imgFile = new File( "${Internal.Transformation.Filename.Directory}/images/logo.png" );
if ( !imgFile.exists() ) {
  throw new KettleException( "Header image not found: " + imgFile.getAbsolutePath() );
}
Defensive patterns

Strategy: validation

Validate before calling

File img = new File( imagePath );
if ( !img.isFile() ) throw new IllegalArgumentException( "Header image missing: " + img.getAbsolutePath() );

Try / catch

try { /* configure header image */ } catch ( KettleException e ) { logError( "Header image error: " + e.getMessage() ); throw e; }

Prevention

When it happens

Trigger: setFonts() is called from openNewFile() when data.realHeaderImage is non-empty and KettleVFS.getFileObject(...).exists() returns false — i.e. the configured header image path resolves to a nonexistent file.

Common situations: Header image filename typo or wrong directory; relative path resolved against a different working directory than expected; image deleted or moved after the step was configured; environment variable in the image path not substituted to a valid location.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

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

    }
    data.headerCellFormat = new WritableCellFormat( writableHeaderFont );

    // Header background color
    if ( meta.getHeaderBackGroundColor() != ExcelOutputMeta.FONT_COLOR_NONE ) {
      data.headerCellFormat.setBackground( ExcelFontMap.getColour( meta.getHeaderBackGroundColor(), null ) );
    }

    // Set alignment
    data.headerCellFormat = ExcelFontMap.getAlignment( meta.getHeaderAlignment(), data.headerCellFormat );
    data.headerCellFormat = ExcelFontMap.getOrientation( meta.getHeaderFontOrientation(), data.headerCellFormat );

    // Do we need to put a image on the header
    if ( !Utils.isEmpty( data.realHeaderImage ) ) {
      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

View on GitHub (pinned to f3058517a1)