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

  1. Inspect the job entry's XML node in the .kjb file, especially the <fields> section and its <count> value
  2. Recreate the XML Well-Formed Validator entry in Spoon and re-save
  3. Validate the whole job file XML for well-formedness
  4. 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

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


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)