pentaho/pentaho-kettle · error · KettleXMLException

GPBulkLoaderMeta.Exception.UnableToReadStepInfoFromXML

GPBulkLoaderMeta.Exception.UnableToReadStepInfoFromXML

Error message

GPBulkLoaderMeta.Exception.UnableToReadStepInfoFromXML

What it means

PGBulkLoaderMeta.readData parses the step's XML (Node) into metadata fields; any exception during parsing is wrapped in a KettleXMLException with the localized message key GPBulkLoaderMeta.Exception.UnableToReadStepInfoFromXML. The step definition could not be loaded from the .ktr file.

Solutions

  1. Open the .ktr in a text editor and inspect/repair the XML under this step's node (fields, field_name, stream_name, date_mask attributes)
  2. Recreate the step in Spoon: add a fresh PGBulkLoader step and reconfigure it, replacing the corrupted one
  3. Check whether the file was produced by an incompatible plugin version and migrate the XML accordingly
  4. Validate the whole .ktr is well-formed XML (xmllint) before re-importing

Example fix

<!-- before (missing fields node) -->
<step name="PG bulk load" type="PGBulkLoader"/>
<!-- after -->
<step name="PG bulk load" type="PGBulkLoader">
  <fields>
    <field stream_name="id" field_name="id" date_mask=""/>
  </fields>
</step>
Defensive patterns

Strategy: validation

Validate before calling

// validate the ktr XML before import
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( new File( "trans.ktr" ) );
if ( doc.getElementsByTagName( "PGBulkLoader" ).getLength() == 0
  || doc.getElementsByTagName( "fields" ).getLength() == 0 ) {
  throw new IllegalStateException( "PGBulkLoader step XML missing required <fields> section" );
}

Try / catch

try {
  transMeta.loadXml( inputStream );
} catch ( KettleXMLException e ) {
  if ( e.getMessage().contains( "UnableToReadStepInfoFromXML" ) ) {
    // inspect the .ktr step node and rebuild the step in Spoon
  }
}

Prevention

When it happens

Trigger: loadXML calls readData and the XML node is malformed or missing expected child elements/attributes (fields, field names, date masks), throwing inside the try block.

Common situations: Hand-edited or truncated .ktr files; XML produced by a different plugin version with a changed schema; copy-pasted step XML missing the <fields> subtree; encoding corruption.

Related errors


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

Appendix: source

Thrown at plugins/postgresql-db-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/pgbulkloader/PGBulkLoaderMeta.java:256

        fieldStream[i] = XMLHandler.getTagValue( vnode, "field_name" );
        if ( fieldStream[i] == null ) {
          fieldStream[i] = fieldTable[i]; // default: the same name!
        }
        String locDateMask = XMLHandler.getTagValue( vnode, "date_mask" );
        if ( locDateMask == null ) {
          dateMask[i] = "";
        } else {
          if ( PGBulkLoaderMeta.DATE_MASK_DATE.equals( locDateMask )
            || PGBulkLoaderMeta.DATE_MASK_PASS_THROUGH.equals( locDateMask )
            || PGBulkLoaderMeta.DATE_MASK_DATETIME.equals( locDateMask ) ) {
            dateMask[i] = locDateMask;
          } else {
            dateMask[i] = "";
          }
        }
      }
    } catch ( Exception e ) {
      throw new KettleXMLException( BaseMessages.getString(
        PKG, "GPBulkLoaderMeta.Exception.UnableToReadStepInfoFromXML" ), e );
    }
  }

  public void setDefault() {
    fieldTable = null;
    databaseMeta = null;
    schemaName = "";
    tableName = BaseMessages.getString( PKG, "GPBulkLoaderMeta.DefaultTableName" );
    dbNameOverride = "";
    delimiter = ";";
    enclosure = "\"";
    stopOnError = false;
    int nrvalues = 0;
    allocate( nrvalues );
  }

  public String getXML() {

View on GitHub (pinned to f3058517a1)