pentaho/pentaho-kettle · error · KettleStepException

Xslt.Exception.ErrorXSLFileNotExists

Error message

Xslt.Exception.ErrorXSLFileNotExists

What it means

The configured XSL stylesheet file does not exist on the filesystem. processRow resolves the filename with environment substitution, obtains a VFS FileObject via KettleVFS, and if !file.exists() logs 'ErrorXSLFileNotExists' and throws this KettleStepException containing the resolved path.

Solutions

  1. Verify the resolved path exists on the machine executing the transformation (note environment substitution of variables).
  2. Use an absolute path or ${Internal.Transformation.Filename.Directory} to anchor the stylesheet relative to the .ktr.
  3. Copy the XSL file to the execution server if running on a cluster/remote agent.
  4. Check the variable value with a 'Get variables' step or Spoon's variable viewer.

Example fix

// before
XSL filename: transform.xsl  // relative, missing on server
// after
XSL filename: ${Internal.Transformation.Filename.Directory}/transform.xsl
Defensive patterns

Strategy: validation

Validate before calling

String path = transMeta.environmentSubstitute(meta.getXslFilename()); java.io.File f = new java.io.File(path); if (!f.exists() || !f.isFile()) { throw new IllegalStateException("XSL file does not exist: " + path); } // before execution

Try / catch

try { step.startThreads(); } catch (KettleStepException e) { if (e.getMessage().contains("ErrorXSLFileNotExists")) { /* check resolved path on the executing host */ } }

Prevention

When it happens

Trigger: processRow's one-time setup: KettleVFS.getFileObject(data.xslfilename).exists() returns false for the environment-substituted XSL filename.

Common situations: Typo in the path; file deployed only on the designer machine but not the execution server/agent; relative path resolved against a different working directory; variable like ${XSL_FILE} unset so path becomes literal or empty; file deleted or renamed after configuration.

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

Appendix: source

Thrown at plugins/xml/core/src/main/java/org/pentaho/di/trans/steps/xslt/Xslt.java:137

              + "]" );
          throw new KettleStepException( BaseMessages.getString( PKG, "Xslt.Exception.ErrorXSLFileFieldFinding", meta
              .getXSLFileField() ) );
        }

      } else {
        if ( Utils.isEmpty( meta.getXslFilename() ) ) {
          logError( BaseMessages.getString( PKG, "Xslt.Log.ErrorXSLFile" ) );
          throw new KettleStepException( BaseMessages.getString( PKG, "Xslt.Exception.ErrorXSLFile" ) );
        }

        // Check if XSL File exists!
        data.xslfilename = environmentSubstitute( meta.getXslFilename() );
        FileObject file = null;
        try {
          file = KettleVFS.getInstance( getTransMeta().getBowl() ).getFileObject( data.xslfilename );
          if ( !file.exists() ) {
            logError( BaseMessages.getString( PKG, "Xslt.Log.ErrorXSLFileNotExists", data.xslfilename ) );
            throw new KettleStepException( BaseMessages.getString( PKG, "Xslt.Exception.ErrorXSLFileNotExists",
                data.xslfilename ) );
          }
          if ( file.getType() != FileType.FILE ) {
            logError( BaseMessages.getString( PKG, "Xslt.Log.ErrorXSLNotAFile", data.xslfilename ) );
            throw new KettleStepException( BaseMessages.getString( PKG, "Xslt.Exception.ErrorXSLNotAFile",
                data.xslfilename ) );
          }
        } catch ( Exception e ) {
          throw new KettleStepException( e );
        } finally {
          try {
            if ( file != null ) {
              file.close();
            }
          } catch ( Exception e ) { /* Ignore */
          }
        }
      }

View on GitHub (pinned to f3058517a1)