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
- 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
- Recreate the Mail Validator step in Spoon and re-save the transformation to regenerate valid XML
- Check Pentaho/PDI version compatibility between the file and the plugins/mail-validator plugin
- 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
- Never hand-edit .ktr XML; edit in Spoon only
- Pin the same PDI/plugin version for authoring and execution
- Keep .ktr files in version control to detect corruption/diff regressions
- Log e.getCause() to see the real parse error
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
- AbortMeta.Exception.UnexpectedErrorInReadingStepInfoFromRepo…
- CloneRowMeta.Exception.UnableToReadStepInfo
- ColumnExistsMeta.Exception.UnableToReadStepInfo
- CreditCardValidatorMeta.Exception.UnableToReadStepInfo
- CubeOutputMeta.Exception.UnableToLoadStepInfo
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)