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
- Identify the plugin named in [jet_code] and install it (drop the plugin jar into plugins/jobentries or install the vendor plugin).
- Upgrade/align your Kettle/Pentaho version with the one that created the job so the built-in plugin exists.
- Fix the repository row: if the stored job entry type code is corrupt, edit R_JOBENTRY to a valid type or delete the entry.
- 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
- Install all third-party/custom job entry plugins on every environment that loads the jobs.
- Use identical Kettle/Pentaho versions across authoring and runtime environments.
- Check plugins/jobentries directory contents after upgrades.
- Before migrating jobs, inventory plugin types used and verify availability in the target system.
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
- Could not execute specified in a repository since we're not…
- database type with plugin id [] couldn't be found!
- database type with plugin id [] couldn't be found!
- ERROR_0002_Cannot_Load_Job_From_Repository
- ERROR_0002_Cannot_Load_Job_From_Repository
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)