pentaho/pentaho-kettle · error · KettleStepException
Xslt.Exception.ErrorXSLNotAFile
Error message
Xslt.Exception.ErrorXSLNotAFile
What it means
Thrown by the XSLT step during processRow when the configured XSL stylesheet path exists but is not a regular file (e.g. it is a directory or a special VFS object). The step resolves the XSL filename through Apache Commons VFS and validates its FileType before using it for transformation. It fails fast because XSLT processing cannot proceed without a valid stylesheet file.
Solutions
- Correct the XSL filename in the step dialog to point to the actual .xsl stylesheet file
- If a variable is used, verify at runtime that it resolves to a full file path ending in the stylesheet, not a directory
- Check the file exists and is a regular file on the filesystem or VFS mount the transformation runs on
Example fix
// before XSL filename: /opt/stylesheets/ // after XSL filename: /opt/stylesheets/transform.xsl
Defensive patterns
Strategy: validation
Validate before calling
// Before running the transformation
File f = new File(xslFilename);
if (!f.exists() || !f.isFile()) {
throw new IllegalArgumentException("XSL path is not a regular file: " + xslFilename);
} Type guard
boolean isValidXslFile(String path) {
File f = new File(path);
return f.exists() && f.isFile() && path.toLowerCase().endsWith(".xsl");
} Prevention
- Always point the XSL field at the stylesheet file, never its parent directory
- Resolve and check variables before deploying the transformation
- Add a 'Check if file exists' style validation step upstream
When it happens
Trigger: The 'XSL File' field in the XSLT step points to a directory, an archive/folder VFS endpoint, or another non-file resource after environmentSubstitute() resolution; file.getType() != FileType.FILE.
Common situations: Typing a folder path instead of the .xsl file; using a variable that resolves to a directory; pointing at an S3/VFS collection; copy-pasting a path without the filename.
Related errors
- Xslt.Exception.ErrorXSLFileNotExists
- [ + ArgList[0] + ] is not a file!
- AvroInputDialog.Error.KettleFileException
- ChangeFileEncoding.Error.ParentFolderNotExist
- ChangeFileEncoding.Error.SourceFileNotAFile
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/4c63365f5d794e8e.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/xml/core/src/main/java/org/pentaho/di/trans/steps/xslt/Xslt.java:142
} 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 */
}
}
}
// Check output parameters
int nrOutputProps = meta.getOutputPropertyName() == null ? 0 : meta.getOutputPropertyName().length;
if ( nrOutputProps > 0 ) {
data.outputProperties = new Properties();View on GitHub (pinned to f3058517a1)