pentaho/pentaho-kettle · error · KettleXMLException

GPLoadMeta.Exception.UnableToReadStepInfoFromXML

Error message

GPLoadMeta.Exception.UnableToReadStepInfoFromXML

What it means

GPLoadMeta.readData() parses the step's XML definition with XMLHandler; any exception during tag reads is wrapped in a KettleXMLException with this message. It indicates the GPload step's XML serialization is malformed or missing expected elements.

Solutions

  1. Open the .ktr in Spoon and reconfigure/save the GPload step to regenerate valid XML
  2. Compare the step's XML block against a freshly created GPload step's XML and repair missing/renamed tags
  3. Align the PDI and GPload plugin versions (the XML schema must match the plugin's readData expectations)
  4. Restore the .ktr from backup if the file was truncated/corrupted

Example fix

// before (missing tag)
<fields><field><name>a</name></field></fields>
// after
<fields><field><name>a</name><field_name>a</field_name><date_mask/><match_column>N</match_column><update_column>N</update_column></field></fields>
Defensive patterns

Strategy: try-catch

Validate before calling

org.w3c.dom.Node stepNode = ...; // verify required tags exist before loadXML
for (String tag : new String[]{"connection","table","data_file","delimiter","fields"}) {
  if (XMLHandler.getTagValue(stepNode, tag) == null && XMLHandler.getSubNode(stepNode, tag) == null) {
    throw new IllegalArgumentException("GPload step XML missing tag: " + tag);
  }
}

Try / catch

try { stepMeta.loadXML(...) } catch (KettleXMLException e) {
  if (e.getMessage().contains("UnableToReadStepInfoFromXML")) { /* fall back to re-creating the step from defaults */ }
  else throw e;
}

Prevention

When it happens

Trigger: loadXML() calls readData on a <step> node whose children (connection, table, field_name/match_column/update_column entries, etc.) are missing, of wrong shape, or whose structure differs from what this plugin version expects.

Common situations: Hand-edited or truncated .ktr files; .ktr created in a different PDI/plugin version with changed XML schema; XML attribute names changed between plugin versions; copy-pasting a GPload step snippet that omits required tags.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at plugins/gpload/core/src/main/java/org/pentaho/di/trans/steps/gpload/GPLoadMeta.java:378

        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 ( GPLoadMeta.DATE_MASK_DATE.equals( locDateMask ) || GPLoadMeta.DATE_MASK_DATETIME.equals( locDateMask ) ) {
            dateMask[i] = locDateMask;
          } else {
            dateMask[i] = "";
          }
        }

        matchColumn[i] = ( "Y".equalsIgnoreCase( XMLHandler.getTagValue( vnode, "match_column" ) ) );
        updateColumn[i] = ( "Y".equalsIgnoreCase( XMLHandler.getTagValue( vnode, "update_column" ) ) );
      }
    } catch ( Exception e ) {
      throw new KettleXMLException( BaseMessages.getString( PKG, "GPLoadMeta.Exception.UnableToReadStepInfoFromXML" ),
          e );
    }
  }

  public void setDefault() {

    // TODO: Make non empty defaults public static Strings

    fieldTable = null;
    databaseMeta = null;
    maxErrors = GPLoadMeta.MAX_ERRORS_DEFAULT;
    schemaName = "";
    localhostPort = "";
    tableName = BaseMessages.getString( PKG, "GPLoadMeta.DefaultTableName" );
    errorTableName = ""; // BaseMessages.getString(PKG, "GPLocal.ErrorTable.Prefix")+tableName;
    loadMethod = METHOD_AUTO_END;
    loadAction = ACTION_INSERT;
    gploadPath = "/usr/local/greenplum-db/bin/gpload";

View on GitHub (pinned to f3058517a1)