pentaho/pentaho-kettle · error · KettleXMLException

Unable to load step info from XML

Error message

Unable to load step info from XML

What it means

FixedInputMeta.readData (invoked by loadXML when parsing a transformation .ktr) wraps XML parsing failures of the fixed-file input step definition in a KettleXMLException with this generic message. Any malformed or unexpected XML for this step triggers it, with the parse exception chained as cause.

Solutions

  1. Open the .ktr in an XML editor and validate the <fields>/<field> structure of this step
  2. Check the chained cause to pinpoint the exact XML attribute that failed
  3. Re-create the step in Spoon and re-save the transformation to regenerate clean XML
  4. Align Kettle/PDI versions between the file's producer and consumer

Example fix

// before
Node fields = XMLHandler.getSubNode( stepnode, "fields" ); // NPE if missing
int nrfields = fields.getChildCount();
// after
Node fields = XMLHandler.getSubNode( stepnode, "fields" );
if ( fields == null ) { fields = XMLHandler.getSubNode( stepnode, "fields" ); allocate( 0 ); return; }
Defensive patterns

Strategy: try-catch

Validate before calling

// validate step XML before loadXML
if ( XMLHandler.getSubNode( stepnode, "fields" ) == null ) {
  throw new IllegalArgumentException( "FixedInput step XML missing <fields> node" );
}

Try / catch

try {
  TransMeta tm = new TransMeta( inputStream, provider, true, variables, listener );
} catch ( KettleXMLException e ) {
  logError( "Load failed: " + e.getCause(), e ); // locate malformed tag
}

Prevention

When it happens

Trigger: loadXML on FixedInputMeta when XMLHandler lookups fail or FixedFileInputField(node) throws — missing <fields> node, malformed <field> entries, or a non-numeric attribute value.

Common situations: Hand-edited or truncated .ktr files; transformations exported from newer Kettle versions with attributes an older version cannot parse; copy-paste corruption of step XML between transformations.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/fixedinput/FixedInputMeta.java:145

      headerPresent = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "header" ) );
      lineFeedPresent = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "line_feed" ) );
      lazyConversionActive = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "lazy_conversion" ) );
      runningInParallel = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "parallel" ) );
      fileType = getFileType( XMLHandler.getTagValue( stepnode, "file_type" ) );
      encoding = XMLHandler.getTagValue( stepnode, "encoding" );
      isaddresult = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "add_to_result_filenames" ) );

      Node fields = XMLHandler.getSubNode( stepnode, "fields" );
      int nrfields = XMLHandler.countNodes( fields, "field" );

      allocate( nrfields );

      for ( int i = 0; i < nrfields; i++ ) {
        Node fnode = XMLHandler.getSubNodeByNr( fields, "field", i );
        fieldDefinition[i] = new FixedFileInputField( fnode );
      }
    } catch ( Exception e ) {
      throw new KettleXMLException( "Unable to load step info from XML", e );
    }
  }

  public void allocate( int nrFields ) {
    fieldDefinition = new FixedFileInputField[nrFields];
  }

  public String getXML() {
    StringBuilder retval = new StringBuilder( 500 );

    retval.append( "    " ).append( XMLHandler.addTagValue( "filename", filename ) );
    retval.append( "    " ).append( XMLHandler.addTagValue( "line_width", lineWidth ) );
    retval.append( "    " ).append( XMLHandler.addTagValue( "header", headerPresent ) );
    retval.append( "    " ).append( XMLHandler.addTagValue( "buffer_size", bufferSize ) );
    retval.append( "    " ).append( XMLHandler.addTagValue( "lazy_conversion", lazyConversionActive ) );
    retval.append( "    " ).append( XMLHandler.addTagValue( "line_feed", lineFeedPresent ) );
    retval.append( "    " ).append( XMLHandler.addTagValue( "parallel", runningInParallel ) );
    retval.append( "    " ).append( XMLHandler.addTagValue( "file_type", getFileTypeCode() ) );

View on GitHub (pinned to f3058517a1)