pentaho/pentaho-kettle · error · KettleXMLException

Unable to load step info from XML

Error message

Unable to load step info from XML

What it means

KettleXMLException thrown by RowGeneratorMeta.readData when any exception occurs while parsing the step's XML <step> node attributes (fields, limit, never_ending, interval_in_ms, row_time_field, last_time_field). loadXML calls readData during transformation deserialization, so a malformed or unexpectedly shaped .ktr file surfaces as this wrapped error.

Solutions

  1. Open the .ktr in a text editor and verify the RowGenerator step's XML block is well-formed and contains the expected tags (fields, limit, never_ending, interval_in_ms, row_time_field, last_time_field).
  2. Read the wrapped cause 'e' in the stack trace to find the exact XML parse failure and fix that line.
  3. Recreate the Row Generator step in Spoon and re-save the transformation to regenerate clean XML.
  4. Confirm the file was produced by a compatible Kettle/Pentaho version; migrate via Spoon rather than manual edits.

Example fix

// before: hand-edited XML missing closing tag
<fields><field>...</fields>
// after: well-formed step XML
<fields><field><name>id</name><type>Integer</type></field></fields>
Defensive patterns

Strategy: try-catch

Validate before calling

// Before loading, validate XML well-formedness
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("trans.ktr"));

Type guard

Node stepNode = XMLHandler.getSubNode(stepnode, "fields");
if (stepNode == null) { throw new IllegalArgumentException("RowGenerator step XML missing <fields> node"); }

Try / catch

try {
  transMeta = new TransMeta("trans.ktr");
} catch (KettleXMLException e) {
  log.error("Failed to parse transformation XML: {}", e.getCause(), e);
  // fall back to a known-good copy of the file
}

Prevention

When it happens

Trigger: loadXML(stepnode, ...) is invoked while loading a transformation from XML and XMLHandler.getTagValue or another call inside readData throws (malformed XML, missing node structure, unexpected null/parse failure in a tag value).

Common situations: Opening a hand-edited or truncated .ktr file; a .ktr produced by a different Pentaho version with different XML attributes; copy-pasting a step XML snippet that is not nested under the expected <step> node; corrupted file transfer.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/rowgenerator/RowGeneratorMeta.java:165

        slength = XMLHandler.getTagValue( fnode, "length" );
        sprecision = XMLHandler.getTagValue( fnode, "precision" );

        fieldLength[i] = Const.toInt( slength, -1 );
        fieldPrecision[i] = Const.toInt( sprecision, -1 );
        String emptyString = XMLHandler.getTagValue( fnode, "set_empty_string" );
        setEmptyString[i] = !Utils.isEmpty( emptyString ) && "Y".equalsIgnoreCase( emptyString );
      }

      // Is there a limit on the number of rows we process?
      rowLimit = XMLHandler.getTagValue( stepnode, "limit" );

      neverEnding = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "never_ending" ) );
      intervalInMs = XMLHandler.getTagValue( stepnode, "interval_in_ms" );
      rowTimeField = XMLHandler.getTagValue( stepnode, "row_time_field" );
      lastTimeField = XMLHandler.getTagValue( stepnode, "last_time_field" );

    } catch ( Exception e ) {
      throw new KettleXMLException( "Unable to load step info from XML", e );
    }
  }

  public void setDefault() {
    int i, nrfields = 0;

    allocate( nrfields );

    DecimalFormat decimalFormat = new DecimalFormat();

    for ( i = 0; i < nrfields; i++ ) {
      fieldName[i] = "field" + i;
      fieldType[i] = "Number";
      fieldFormat[i] = "\u00A40,000,000.00;\u00A4-0,000,000.00";
      fieldLength[i] = 9;
      fieldPrecision[i] = 2;
      currency[i] = decimalFormat.getDecimalFormatSymbols().getCurrencySymbol();
      decimal[i] = new String( new char[] { decimalFormat.getDecimalFormatSymbols().getDecimalSeparator() } );

View on GitHub (pinned to f3058517a1)