pentaho/pentaho-kettle · error · KettleXMLException

WriteToLog.Error.UnableToLoadFromXML.Label

Error message

WriteToLog.Error.UnableToLoadFromXML.Label

What it means

JobEntryWriteToLog.loadXML() throws this KettleXMLException when the job entry's configuration cannot be read from its XML <entry> node. It wraps any exception from XMLHandler.getTagValue or LogLevel.getLogLevelForCode (e.g. malformed or missing XML elements, bad log-level code) into a localized message with the original exception as cause.

Solutions

  1. Open the .kjb file in a text editor and verify the job entry node contains well-formed 'logmessage', 'loglevel', and 'logsubject' child tags
  2. Check the cause exception (KettleXMLException.getCause()) to identify the exact parse failure
  3. Re-export or re-save the job from Spoon so it writes a valid XML node
  4. Upgrade/align the Pentaho Kettle engine version with the version that created the job file

Example fix

// before: broken XML node
<entry name='Write to log'><loglevel>Z</loglevel></entry>
// after: valid node
<entry name='Write to log'><logmessage>Hello</logmessage><loglevel>Basic</loglevel><logsubject>Job</logsubject></entry>
Defensive patterns

Strategy: try-catch

Validate before calling

// validate before loadXML
Node entrynode = XMLHandler.getSubNode( jobNode, "entry" );
if ( entrynode == null ) throw new KettleXMLException( "Missing <entry> node" );
if ( XMLHandler.getTagValue( entrynode, "loglevel" ) == null ) throw new KettleXMLException( "Missing loglevel tag" );

Type guard

boolean isValidEntryNode( Node n ) {
  return n != null && XMLHandler.getTagValue( n, "loglevel" ) != null
    && XMLHandler.getTagValue( n, "logmessage" ) != null;
}

Try / catch

try {
  jobEntry.loadXML( entrynode, databases, slaveServers, rep, metaStore );
} catch ( KettleXMLException e ) {
  logError( "WriteToLog entry XML load failed: " + e.getCause(), e );
  // fall back to defaults or abort transformation load
}

Prevention

When it happens

Trigger: Calling loadXML on a job entry XML node where the 'logmessage', 'loglevel', or 'logsubject' elements are unreadable/parsing fails (XMLHandler throws), or the 'loglevel' tag value causes LogLevel.getLogLevelForCode to fail, or super.loadXML itself throws.

Common situations: Hand-edited or truncated .kjb job files; XML produced by a newer Pentaho version being loaded by an older engine; corrupt export files; copy-pasted entry nodes missing expected child tags.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/job/entries/writetolog/JobEntryWriteToLog.java:103

    retval.append( super.getXML() );
    retval.append( "      " ).append( XMLHandler.addTagValue( "logmessage", logmessage ) );
    retval.append( "      " ).append(
      XMLHandler.addTagValue( "loglevel", ( getEntryLogLevel() == null ) ? null : getEntryLogLevel().getCode() ) );
    retval.append( "      " ).append( XMLHandler.addTagValue( "logsubject", logsubject ) );

    return retval.toString();
  }

  @Override
  public void loadXML( Node entrynode, List<DatabaseMeta> databases, List<SlaveServer> slaveServers,
    Repository rep, IMetaStore metaStore ) throws KettleXMLException {
    try {
      super.loadXML( entrynode, databases, slaveServers );
      logmessage = XMLHandler.getTagValue( entrynode, "logmessage" );
      entryLogLevel = LogLevel.getLogLevelForCode( XMLHandler.getTagValue( entrynode, "loglevel" ) );
      logsubject = XMLHandler.getTagValue( entrynode, "logsubject" );
    } catch ( Exception e ) {
      throw new KettleXMLException( BaseMessages.getString( PKG, "WriteToLog.Error.UnableToLoadFromXML.Label" ), e );

    }
  }

  @Override
  public void loadRep( Repository rep, IMetaStore metaStore, ObjectId id_jobentry, List<DatabaseMeta> databases,
    List<SlaveServer> slaveServers ) throws KettleException {
    try {
      logmessage = rep.getJobEntryAttributeString( id_jobentry, "logmessage" );
      entryLogLevel = LogLevel.getLogLevelForCode( rep.getJobEntryAttributeString( id_jobentry, "loglevel" ) );
      logsubject = rep.getJobEntryAttributeString( id_jobentry, "logsubject" );
    } catch ( KettleDatabaseException dbe ) {
      throw new KettleException( BaseMessages.getString( PKG, "WriteToLog.Error.UnableToLoadFromRepository.Label" )
        + id_jobentry, dbe );

    }
  }

View on GitHub (pinned to f3058517a1)