pentaho/pentaho-kettle · error · KettleXMLException
JobXMLWellFormed.Error.Exception.UnableLoadXML
JobXMLWellFormed.Error.Exception.UnableLoadXML
Error message
JobXMLWellFormed.Error.Exception.UnableLoadXML
What it means
JobEntryXMLWellFormed.loadXML() failed while parsing the job entry's XML node (reading source_filefolder/wildcard arrays and related fields). The KettleXMLException from XMLHandler is wrapped and rethrown with the localized message 'UnableLoadXML', meaning the XML Well-Formed Validator entry could not be deserialized from the job file.
Solutions
- Inspect the job entry's XML node in the .kjb file, especially the <fields> section and its <count> value
- Recreate the XML Well-Formed Validator entry in Spoon and re-save
- Validate the whole job file XML for well-formedness
- Check for version mismatch between the file and the PDI engine
Defensive patterns
Strategy: try-catch
Validate before calling
// validate the <fields><count> matches actual field nodes before load // parse job.kjb and check that fields/count equals number of <field> children
Try / catch
try {
jobMeta.loadXml( jobFile );
} catch ( KettleXMLException e ) {
if ( e.getMessage().contains( "UnableLoadXML" ) || e.getMessage().contains( "XMLWellFormed" ) ) {
logError( "XMLWellFormed entry node corrupt; fix <fields> section in job file" );
} else { throw e; }
} Prevention
- Do not hand-edit the <fields> block; add rows through the step dialog
- Keep the fields count consistent with the number of field nodes
- Back up job files before edits or version migrations
- Recreate entries that fail to load instead of patching XML manually
When it happens
Trigger: loadXML() reads fields files count, source_filefolder[i], wildcard[i] etc. from entrynode and XMLHandler throws KettleXMLException due to malformed/missing tags in the job XML.
Common situations: Job file hand-edited so the <fields> section is inconsistent with the declared row count; truncated .kjb file; PDI version tag changes; encoding corruption.
Related errors
- JobEntryAbort.UnableToLoadFromXml.Label
- JobEntryAddResultFilenames.UnableToLoadFromXml
- JobEntryCheckFilesLocked.UnableToLoadFromXml
- JobEntryColumnsExist.Meta.UnableLoadXml
- JobEntryConnectedToRepository.Meta.UnableToLoadFromXML
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/70ec3540be5a94a7.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/xml/core/src/main/java/org/pentaho/di/job/entries/xmlwellformed/JobEntryXMLWellFormed.java:174
resultfilenames = XMLHandler.getTagValue( entrynode, "resultfilenames" );
Node fields = XMLHandler.getSubNode( entrynode, "fields" );
// How many field arguments?
int nrFields = XMLHandler.countNodes( fields, "field" );
source_filefolder = new String[nrFields];
wildcard = new String[nrFields];
// Read them all...
for ( int i = 0; i < nrFields; i++ ) {
Node fnode = XMLHandler.getSubNodeByNr( fields, "field", i );
source_filefolder[i] = XMLHandler.getTagValue( fnode, "source_filefolder" );
wildcard[i] = XMLHandler.getTagValue( fnode, "wildcard" );
}
} catch ( KettleXMLException xe ) {
throw new KettleXMLException( BaseMessages.getString( PKG, "JobXMLWellFormed.Error.Exception.UnableLoadXML" ), xe );
}
}
public void loadRep( Repository rep, IMetaStore metaStore, ObjectId id_jobentry, List<DatabaseMeta> databases,
List<SlaveServer> slaveServers ) throws KettleException {
try {
arg_from_previous = rep.getJobEntryAttributeBoolean( id_jobentry, "arg_from_previous" );
include_subfolders = rep.getJobEntryAttributeBoolean( id_jobentry, "include_subfolders" );
nr_errors_less_than = rep.getJobEntryAttributeString( id_jobentry, "nr_errors_less_than" );
success_condition = rep.getJobEntryAttributeString( id_jobentry, "success_condition" );
resultfilenames = rep.getJobEntryAttributeString( id_jobentry, "resultfilenames" );
// How many arguments?
int argnr = rep.countNrJobEntryAttributes( id_jobentry, "source_filefolder" );
source_filefolder = new String[argnr];
wildcard = new String[argnr];
View on GitHub (pinned to f3058517a1)