pentaho/pentaho-kettle · error · KettleXMLException

MailValidatorMeta.Exception.UnableToReadStepInfo

Error message

MailValidatorMeta.Exception.UnableToReadStepInfo

What it means

Thrown by MailValidatorMeta.readData() when parsing the step's XML definition fails. This step metadata loader reads attributes (emailSender, defaultSMTPField, isdynamicDefaultSMTP) from the transformation XML via XMLHandler; any exception while reading those tags is wrapped in a KettleXMLException so callers know the step could not be deserialized. It is a serialization/deserialization error, not a runtime mail error.

Solutions

  1. Open the .ktr in a text editor and verify the mail-validator step's XML node is well-formed and contains emailSender/defaultSMTPField/isdynamicDefaultSMTP tags
  2. Recreate the Mail Validator step in Spoon and re-save the transformation to regenerate valid XML
  3. Check Pentaho/PDI version compatibility between the file and the plugins/mail-validator plugin
  4. Enable Kettle debug logging to see the wrapped cause (e) of the KettleXMLException

Example fix

// before: hand-edited broken node
<step name='Mail Validator'><emailSender>no closing tag
// after: valid node
<step name='Mail Validator'><emailSender>sender@example.com</emailSender><defaultSMTPField></defaultSMTPField><isdynamicDefaultSMTP>N</isdynamicDefaultSMTP></step>
Defensive patterns

Strategy: validation

Validate before calling

// Validate the ktr XML before loading
javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder()
  .parse(new java.io.File('trans.ktr')); // throws if malformed
// then check the step node exists
// NodeList steps = doc.getElementsByTagName("step"); ensure mail-validator fields present

Type guard

boolean hasMailValidatorFields(org.w3c.dom.Element step) {
  return step != null && step.getElementsByTagName("emailSender").getLength() > 0;
}

Try / catch

try {
  transMeta = new TransMeta('trans.ktr');
} catch (KettleXMLException e) {
  log.error('Corrupt step XML in trans.ktr: ' + e.getCause(), e);
  throw new IllegalStateException('Fix or recreate the mail-validator step XML', e);
}

Prevention

When it happens

Trigger: loadXML() calls readData() with a stepnode element that is malformed, missing required tags, or whose child elements cannot be parsed by XMLHandler.getTagValue; an underlying exception (e.g. DOM/NPE) is raised inside the try block.

Common situations: Hand-edited or corrupted .ktr files; transformations written by a newer/older Pentaho version with different XML schema; truncated XML files; XML where the mail-validator step node has invalid nested elements.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at plugins/mail-validator/impl/src/main/java/org/pentaho/di/trans/steps/mailvalidator/MailValidatorMeta.java:387

  private void readData( Node stepnode ) throws KettleXMLException {
    try {
      emailfield = XMLHandler.getTagValue( stepnode, "emailfield" );
      resultfieldname = XMLHandler.getTagValue( stepnode, "resultfieldname" );
      ResultAsString = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "ResultAsString" ) );
      smtpCheck = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "smtpCheck" ) );

      emailValideMsg = XMLHandler.getTagValue( stepnode, "emailValideMsg" );
      emailNotValideMsg = XMLHandler.getTagValue( stepnode, "emailNotValideMsg" );
      errorsFieldName = XMLHandler.getTagValue( stepnode, "errorsFieldName" );
      timeout = XMLHandler.getTagValue( stepnode, "timeout" );
      defaultSMTP = XMLHandler.getTagValue( stepnode, "defaultSMTP" );
      emailSender = XMLHandler.getTagValue( stepnode, "emailSender" );
      defaultSMTPField = XMLHandler.getTagValue( stepnode, "defaultSMTPField" );

      isdynamicDefaultSMTP = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "isdynamicDefaultSMTP" ) );

    } catch ( Exception e ) {
      throw new KettleXMLException( BaseMessages.getString(
        PKG, "MailValidatorMeta.Exception.UnableToReadStepInfo" ), e );
    }
  }

  public void readRep( Repository rep, IMetaStore metaStore, ObjectId id_step, List<DatabaseMeta> databases ) throws KettleException {
    try {
      emailfield = rep.getStepAttributeString( id_step, "emailfield" );
      resultfieldname = rep.getStepAttributeString( id_step, "resultfieldname" );
      ResultAsString = rep.getStepAttributeBoolean( id_step, "ResultAsString" );
      smtpCheck = rep.getStepAttributeBoolean( id_step, "smtpCheck" );

      emailValideMsg = rep.getStepAttributeString( id_step, "emailValideMsg" );
      emailNotValideMsg = rep.getStepAttributeString( id_step, "emailNotValideMsg" );
      errorsFieldName = rep.getStepAttributeString( id_step, "errorsFieldName" );
      timeout = rep.getStepAttributeString( id_step, "timeout" );
      defaultSMTP = rep.getStepAttributeString( id_step, "defaultSMTP" );
      emailSender = rep.getStepAttributeString( id_step, "emailSender" );
      defaultSMTPField = rep.getStepAttributeString( id_step, "defaultSMTPField" );

View on GitHub (pinned to f3058517a1)