pentaho/pentaho-kettle · error · KettleException

JobEntryLoader was unable to find Job Entry Plugin with…

Error message

JobEntryLoader was unable to find Job Entry Plugin with description [jet_code].

What it means

When loading a job entry copy from the repository, the stored job entry type code (jet_code) is resolved through JobEntryLoader's plugin registry. If no registered job entry plugin matches that code, loadJobEntryCopy throws this KettleException, meaning the repository contains a job entry whose plugin is not installed in the current runtime.

Solutions

  1. Identify the plugin named in [jet_code] and install it (drop the plugin jar into plugins/jobentries or install the vendor plugin).
  2. Upgrade/align your Kettle/Pentaho version with the one that created the job so the built-in plugin exists.
  3. Fix the repository row: if the stored job entry type code is corrupt, edit R_JOBENTRY to a valid type or delete the entry.
  4. As a fallback, replace the missing job entry in the job with an equivalent available entry and re-save.

Example fix

// before
JobMeta job = (JobMeta) repository.loadJob(name, directory, monitor, null); // throws: plugin 'jet_code' missing
// after
// 1. install the plugin jar in plugins/jobentries/ (or matching vendor plugin)
// 2. verify registration before loading:
PluginRegistry registry = PluginRegistry.getInstance();
if (registry.getPlugin(JobEntryPluginType.class, jetCode) == null) {
  logError("Job entry plugin " + jetCode + " not installed; install it before loading this job");
}
Defensive patterns

Strategy: validation

Validate before calling

PluginRegistry registry = PluginRegistry.getInstance();
String jetCode = /* job entry type code stored in repository */;
if (registry.getPlugin(JobEntryPluginType.class, jetCode) == null) {
  throw new IllegalStateException("Job entry plugin not installed: " + jetCode);
}

Type guard

boolean isJobEntryPluginAvailable(String code) {
  return code != null && PluginRegistry.getInstance()
    .getPlugin(JobEntryPluginType.class, code) != null;
}

Try / catch

try {
  JobMeta job = (JobMeta) repository.loadJob(name, dir, monitor, null);
} catch (KettleException e) {
  if (e.getMessage() != null && e.getMessage().contains("JobEntryLoader was unable to find")) {
    logError("Install the missing job entry plugin, then reload the job", e);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling repository.loadJob (via loadJobEntryCopy) when the R_JOBENTRY row's code/description has no matching plugin id in JobEntryLoader's registry - i.e. JobEntryLoader.lookup() (findJobEntry) returns null for the stored type code.

Common situations: Loading a job created in another Pentaho/Kettle installation with third-party or custom job entry plugins not installed locally; version downgrade where the plugin was removed; corrupted job entry type column in the repository row; plugins directory missing jars.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryJobEntryDelegate.java:165

              // THIS IS THE PLUGIN/JOB-ENTRY BEING LOADED!
              //

              // If you extended the JobEntryBase class, you're fine.
              // Otherwise you're on your own.
              //
              if ( jobEntry instanceof JobEntryBase ) {
                loadJobEntryBase( (JobEntryBase) jobEntry, jobEntryId, databases, slaveServers );
                ( (JobEntryBase) jobEntry ).setAttributesMap( loadJobEntryAttributesMap( jobId, jobEntryId ) );
              }

              compatibleJobEntryLoadRep( jobEntry, repository, jobEntryTypeId, databases, slaveServers );
              jobEntry.loadRep( repository, repository.metaStore, jobEntryId, databases, slaveServers );

              jobEntryCopy.getEntry().setObjectId( jobEntryId );

              jobentries.add( jobEntryCopy.getEntry() );
            } else {
              throw new KettleException( "JobEntryLoader was unable to find Job Entry Plugin with description ["
                + jet_code + "]." );
            }
          } else {
            throw new KettleException( "Unable to find Job Entry Type with id="
              + jobEntryTypeId + " in the repository" );
          }
        }

        jobEntryCopy.setLocation( locx, locy );
        jobEntryCopy.setDrawn( isdrawn );
        jobEntryCopy.setLaunchingInParallel( isparallel );

        return jobEntryCopy;
      } else {
        throw new KettleException( "Unable to find job entry copy in repository with id_jobentry_copy="
          + jobEntryCopyId );
      }
    } catch ( KettleDatabaseException dbe ) {

View on GitHub (pinned to f3058517a1)