pentaho/pentaho-kettle · error · KettleXMLException

Unable to load job entry of type 'mail' from XML node

Error message

Unable to load job entry of type 'mail' from XML node

What it means

Outer catch-all while loading the 'mail' job entry from its XML node: an exception occurred parsing the entry's settings (zip options, reply-to, embedded images). The message identifies the entry type; the underlying exception is chained.

Solutions

  1. Inspect the chained KettleException cause to find the exact XML node/tag that failed to parse.
  2. Open the .kjb in Spoon and re-save the Mail job entry to regenerate well-formed XML.
  3. Restore the job file from version control if it was hand-edited or truncated.
  4. Match Pentaho/PDI versions if the job came from a different release.
Defensive patterns

Strategy: validation

Validate before calling

// Validate the job XML before loading
Document doc = XMLHandler.loadXMLFile(new File(jobFile));
if (doc == null || XMLHandler.getSubNode(doc, "job") == null) {
  throw new KettleException(jobFile + " is not a valid job XML file.");
}

Try / catch

try { loadJob(xmlNode); } catch (KettleXMLException e) {
  logError("Mail job entry XML is malformed; re-save the .kjb in Spoon: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: loadXML reads embedded image nodes and tags from the entrynode and any malformed/missing node or unexpected structure raises KettleException, e.g. a hand-edited .kjb or a file written by an incompatible Pentaho version.

Common situations: Hand-edited job XML with broken <embedded_image> nodes; jobs from newer/older Pentaho versions with changed XML schema; truncated file from a failed VCS merge.

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

Appendix: source

Thrown at plugins/mail-job/impl/src/main/java/org/pentaho/di/job/entries/mail/JobEntryMail.java:419

      setZipFiles( "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, TAG_ZIP_FILES ) ) );
      setZipFilename( XMLHandler.getTagValue( entrynode, TAG_ZIP_NAME ) );
      setReplyToAddresses( XMLHandler.getTagValue( entrynode, TAG_REPLY_TO_ADDRESSES ) );

      Node images = XMLHandler.getSubNode( entrynode, TAG_EMBEDDED_IMAGES );

      // How many field embedded images ?
      int nrImages = XMLHandler.countNodes( images, TAG_EMBEDDED_IMAGE );
      allocateImages( nrImages );

      // Read them all...
      for ( int i = 0; i < nrImages; i++ ) {
        Node fnode = XMLHandler.getSubNodeByNr( images, TAG_EMBEDDED_IMAGE, i );

        embeddedimages[i] = XMLHandler.getTagValue( fnode, TAG_IMAGE_NAME );
        contentids[i] = XMLHandler.getTagValue( fnode, TAG_CONTENT_ID );
      }
    } catch ( KettleException xe ) {
      throw new KettleXMLException( "Unable to load job entry of type 'mail' from XML node", xe );
    }
  }

  @Override
  public void loadRep( Repository rep, IMetaStore metaStore, ObjectId idJobEntry, List<DatabaseMeta> databases,
    List<SlaveServer> slaveServers ) throws KettleException {
    try {
      // First load the common parts like name & description, then the attributes...
      //
      server = rep.getJobEntryAttributeString( idJobEntry, TAG_SERVER );
      port = rep.getJobEntryAttributeString( idJobEntry, TAG_PORT );
      destination = rep.getJobEntryAttributeString( idJobEntry, TAG_DESTINATION );
      destinationCc = rep.getJobEntryAttributeString( idJobEntry, TAG_DESTINATION_CC );
      destinationBCc = rep.getJobEntryAttributeString( idJobEntry, TAG_DESTINATION_BCC );
      replyAddress = rep.getJobEntryAttributeString( idJobEntry, TAG_REPLYTO );
      replyName = rep.getJobEntryAttributeString( idJobEntry, TAG_REPLYTONAME );
      subject = rep.getJobEntryAttributeString( idJobEntry, TAG_SUBJECT );
      includeDate = rep.getJobEntryAttributeBoolean( idJobEntry, TAG_INCLUDE_DATE );

View on GitHub (pinned to f3058517a1)