pentaho/pentaho-kettle · error · KettleException

Unable to perform logging at transformation end!

Error message

Unable to perform logging at transformation end!

What it means

Registered as a jobFinished listener for the transformation-style log channel; if writeLogChannelInformation() throws at job end, the KettleException is re-wrapped with this (historically trans-oriented) message. Note the message text mentions transformation even though this is the Job class.

Solutions

  1. Check the chained cause for the underlying error
  2. Verify the channel log table is defined and matches expected schema
  3. Confirm connectivity to the logging database at job end
  4. Upgrade/align log table DDL after Kettle version changes
Defensive patterns

Strategy: try-catch

Validate before calling

if (channelLogTable != null && channelLogTable.isDefined()) {
  ResultSet rs = conn.getMetaData().getTables(null, null, channelLogTable.getTableName(), null);
  if (!rs.next()) throw new IllegalStateException("Channel log table missing");
}

Try / catch

try {
  job.run();
} catch (KettleException e) {
  if (e.getMessage().contains("Unable to perform logging")) {
    log.error("Channel log write failed at job end", e.getCause());
  }
}

Prevention

When it happens

Trigger: At job end, writing the log channel (LoggingHierarchy / channel log) information to the channel log table throws a KettleException.

Common situations: Channel log table undefined/misconfigured in logging settings; DB connection lost during the run; channel log table schema mismatch after a Kettle upgrade.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/job/Job.java:1141

            throw new KettleException( BaseMessages.getString( PKG,
                "Job.Exception.UnableToPerformJobEntryLoggingAtJobEnd" ), e );
          }
        }
      } );
    }

    // If we need to write the log channel hierarchy and lineage information,
    // add a listener for that too...
    //
    ChannelLogTable channelLogTable = jobMeta.getChannelLogTable();
    if ( channelLogTable.isDefined() ) {
      addJobListener( new JobAdapter() {

        @Override public void jobFinished( Job job ) throws KettleException {
          try {
            writeLogChannelInformation();
          } catch ( KettleException e ) {
            throw new KettleException( BaseMessages.getString( PKG, "Job.Exception.UnableToPerformLoggingAtTransEnd" ),
                e );
          }
        }
      } );
    }

    JobExecutionExtension extension = new JobExecutionExtension( this, result, null, false );
    ExtensionPointHandler.callExtensionPoint( log, KettleExtensionPoint.JobBeginProcessing.id, extension );

    return true;
  }

  //
  // Handle logging at end
  /**
   * End processing.
   *
   * @return true, if successful

View on GitHub (pinned to f3058517a1)