pentaho/pentaho-kettle · error · KettleXMLException

MySQLBulkLoaderMeta.Exception.UnableToReadStepInfoFromXML

MySQLBulkLoaderMeta.Exception.UnableToReadStepInfoFromXML

Error message

MySQLBulkLoaderMeta.Exception.UnableToReadStepInfoFromXML

What it means

readData parses the step's XML representation (via loadXML) and wraps any exception during tag parsing in a KettleXMLException with the UnableToReadStepInfoFromXML message. It means the <step> XML for the MySQL Bulk Loader could not be read: a required tag was missing, malformed, or had an unexpected value. The original exception is attached as the cause.

Solutions

  1. Open the .ktr file in a text editor and inspect the MySQL Bulk Loader step's <fields> section for missing or malformed tags (field_table, field_stream, field_format_ok).
  2. Recreate the step in Spoon and save a fresh .ktr to regenerate valid XML.
  3. Check Kettle version compatibility — if the file came from a newer PDI version, upgrade the runtime or re-save in your version.
  4. Look at the KettleXMLException's cause (getCause()) to pinpoint the exact parse failure.

Example fix

// before: hand-edited XML with an unrecognized format value
<field_format_ok>BigDecimal</field_format_ok>
// after: use one of the supported format identifiers
<field_format_ok>none</field_format_ok>
Defensive patterns

Strategy: try-catch

Validate before calling

// Before loading, check the .ktr contains well-formed step XML
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( new File( ktrPath ) );
NodeList steps = doc.getElementsByTagName( "step" );
for ( int i = 0; i < steps.getLength(); i++ ) {
  Element step = (Element) steps.item( i );
  if ( "MySQLBulkLoader".equals( step.getAttribute( "type" ) ) ) {
    NodeList fields = step.getElementsByTagName( "fields" );
    if ( fields.getLength() == 0 ) {
      throw new IllegalStateException( "MySQLBulkLoader step XML missing <fields> element" );
    }
  }
}

Try / catch

try {
  transMeta = new TransMeta( ktrPath );
} catch ( KettleXMLException e ) {
  if ( String.valueOf( e.getMessage() ).contains( "UnableToReadStepInfoFromXML" ) ) {
    log.error( "Corrupt MySQL Bulk Loader step XML; inspect the <fields> block, cause:", e.getCause() );
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: loadXML -> readData throws when XMLHandler.getTagValue returns unexpected content, getFieldFormatType fails on an unknown format string, or any exception occurs while reading field_table/field_stream/field_format_ok tags inside the <fields> element.

Common situations: Manually edited .ktr files with corrupted or missing tags; transformations from a different Pentaho/Kettle version using a different XML schema; truncated file transfer; copy-pasted step XML between transformations with mismatched content.

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/0e935b61518975b9. Report an issue: GitHub.

Appendix: source

Thrown at plugins/mysql-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/mysqlbulkloader/MySQLBulkLoaderMeta.java:275

      replacingData = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "replace" ) );
      ignoringErrors = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "ignore" ) );
      localFile = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "local" ) );

      int nrvalues = XMLHandler.countNodes( stepnode, "mapping" );
      allocate( nrvalues );

      for ( int i = 0; i < nrvalues; i++ ) {
        Node vnode = XMLHandler.getSubNodeByNr( stepnode, "mapping", i );

        fieldTable[i] = XMLHandler.getTagValue( vnode, "stream_name" );
        fieldStream[i] = XMLHandler.getTagValue( vnode, "field_name" );
        if ( fieldStream[i] == null ) {
          fieldStream[i] = fieldTable[i]; // default: the same name!
        }
        fieldFormatType[i] = getFieldFormatType( XMLHandler.getTagValue( vnode, "field_format_ok" ) );
      }
    } catch ( Exception e ) {
      throw new KettleXMLException( BaseMessages.getString( PKG,
          "MySQLBulkLoaderMeta.Exception.UnableToReadStepInfoFromXML" ), e );
    }
  }

  public void setDefault() {
    fieldTable = null;
    databaseMeta = null;
    schemaName = "";
    tableName = BaseMessages.getString( PKG, "MySQLBulkLoaderMeta.DefaultTableName" );
    encoding = "";
    fifoFileName = "/tmp/fifo";
    delimiter = "\t";
    enclosure = "\"";
    escapeChar = "\\";
    replacingData = false;
    ignoringErrors = false;
    localFile = true;
    bulkSize = null;

View on GitHub (pinned to f3058517a1)