apache/seatunnel · error · RuntimeException
Plugin %s not found.
Error message
Plugin %s not found.
What it means
AbstractPluginDiscovery.createPluginInstance throws a RuntimeException('Plugin <identifier> not found.') when createOptionalPluginInstance returns empty — i.e. no plugin class implementing the requested plugin identifier could be located via the plugin mapping config or discovered SPI files, even after considering the supplied plugin jars.
Source
Thrown at seatunnel-plugin-discovery/src/main/java/org/apache/seatunnel/plugin/discovery/AbstractPluginDiscovery.java:270
if (pluginInstance != null) {
log.info(
"Load plugin: {} from path: {} use classloader: {}",
pluginIdentifier,
pluginJarPaths.get(),
classLoader.getClass().getName());
return Optional.of(pluginInstance);
}
}
return Optional.empty();
}
@Override
public T createPluginInstance(PluginIdentifier pluginIdentifier, Collection<URL> pluginJars) {
Optional<T> instance = createOptionalPluginInstance(pluginIdentifier, pluginJars);
if (instance.isPresent()) {
return instance.get();
}
throw new RuntimeException("Plugin " + pluginIdentifier + " not found.");
}
@Override
public ImmutableTriple<PluginIdentifier, List<Option<?>>, List<Option<?>>> getOptionRules(
String pluginIdentifier) {
Optional<Map.Entry<PluginIdentifier, OptionRule>> pluginEntry =
getPlugins().entrySet().stream()
.filter(
entry ->
entry.getKey()
.getPluginName()
.equalsIgnoreCase(pluginIdentifier))
.findFirst();
if (pluginEntry.isPresent()) {
Map.Entry<PluginIdentifier, OptionRule> entry = pluginEntry.get();
List<Option<?>> requiredOptions =
entry.getValue().getRequiredOptions().stream()
.flatMap(requiredOption -> requiredOption.getOptions().stream())View on GitHub (pinned to cf67b549a7)
Solutions
- Check plugin-mapping.properties under $SEATUNNEL_HOME/connectors contains an entry mapping the plugin name to its factory class
- Install the connector jar: run sh bin/install-plugin.sh <version> or copy the jar to the connectors directory
- Verify the exact plugin name in your job config against the discovered plugin list; fix typos and case
- For custom plugins, ensure META-INF/services/<FactoryClass> SPI registration exists and the class is public with a no-arg constructor
Example fix
// before (job config)
sink {
Jdbc-mydb { ... } // typo / unregistered name
}
// after
sink {
Jdbc {
url = "jdbc:mysql://..."
...
}
} Defensive patterns
Strategy: validation
Validate before calling
Properties mapping = new Properties();
mapping.load(new FileInputStream("$SEATUNNEL_HOME/connectors/plugin-mapping.properties"));
if (!mapping.containsKey(engineType + "." + pluginName)) {
throw new IllegalStateException("Plugin not registered: " + pluginName);
} Type guard
boolean pluginRegistered(Properties pluginMapping, PluginIdentifier id) {
return pluginMapping.containsKey(id.getPluginEngineType() + "." + id.getPluginName());
} Try / catch
try {
T plugin = discovery.createPluginInstance(pluginIdentifier, pluginJars);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Plugin ") && e.getMessage().endsWith(" not found.")) {
throw new IllegalStateException("Install jar / check plugin name: " + pluginIdentifier, e);
}
throw e;
} Prevention
- Verify plugin names against plugin-mapping.properties before submitting jobs
- Run sh bin/install-plugin.sh to install connector jars after upgrading SeaTunnel
- For custom plugins, always register META-INF/services SPI files and a public no-arg constructor
When it happens
Trigger: Requesting a plugin by PluginIdentifier (engine type + plugin name) whose name is absent from plugin-mapping.properties, whose class is not on the classpath/plugin dir, or whose jar was not provided/found; also when the mapped class fails to load/instantiate so the Optional is empty.
Common situations: Typo in the plugin name in the job config (e.g. 'Jdbc-mydb' vs 'Jdbc'); connector jar not installed under $SEATUNNEL_HOME/connectors; version mismatch where the plugin identifier changed between SeaTunnel versions; custom plugin missing META-INF/services registration.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- CONFIG_VALIDATION_FAILED
- plugin dir: {} not exists, load plugin from classpath
- Could not find any factories that implement '%s' in the clas
- Multiple factories for identifier '%s' that implement '%s' f
- Could not load service provider for factories.
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/d65bf346e8c17a43.
Report an issue: GitHub.