apache/seatunnel · error · RuntimeException
Can not find any plugin(source/sink/transform) in the dir: %
Error message
Can not find any plugin(source/sink/transform) in the dir: %s
What it means
AbstractPluginDiscovery scans the plugin directory for connector jars during plugin discovery. If the plugin directory exists but its jar files cannot be listed due to an IOException (e.g. I/O permission or filesystem errors), it wraps this into a RuntimeException stating no plugins can be found in that dir.
Source
Thrown at seatunnel-plugin-discovery/src/main/java/org/apache/seatunnel/plugin/discovery/AbstractPluginDiscovery.java:377
"seatunnel",
PluginType.TRANSFORM.getType(),
plugin.factoryIdentifier()),
plugin.optionRule());
return;
}
});
return plugins;
}
protected List<Factory> getPluginFactories() {
List<Factory> factories;
if (this.pluginDir.toFile().exists()) {
log.debug("load plugin from plugin dir: {}", this.pluginDir);
List<URL> files;
try {
files = FileUtils.searchJarFiles(this.pluginDir);
} catch (IOException e) {
throw new RuntimeException(
String.format(
"Can not find any plugin(source/sink/transform) in the dir: %s",
this.pluginDir));
}
factories =
FactoryUtil.discoverFactories(new URLClassLoader(files.toArray(new URL[0])));
} else {
log.warn("plugin dir: {} not exists, load plugin from classpath", this.pluginDir);
factories =
FactoryUtil.discoverFactories(Thread.currentThread().getContextClassLoader());
}
return factories;
}
protected T loadPluginInstance(PluginIdentifier pluginIdentifier, ClassLoader classLoader) {
ServiceLoader<T> serviceLoader = ServiceLoader.load(getPluginBaseClass(), classLoader);
for (T t : serviceLoader) {
if (t instanceof PluginIdentifierInterface) {View on GitHub (pinned to cf67b549a7)
Solutions
- Verify the connector plugin directory exists, is a directory, and is readable by the SeaTunnel process user
- Check SEATUNNEL_HOME and the plugin-dir resolution (options like --plugin-dir) point to the correct install location
- Run sh bin/install-plugin.sh to reinstall missing connector jars into the plugin dir
- Inspect filesystem permissions/ACLs or mount health on the plugin directory
Example fix
// before (broken env) SEATUNNEL_HOME=/opt/wrong-path bin/seatunnel.sh --config job.conf // after SEATUNNEL_HOME=/opt/seatunnel bin/seatunnel.sh --config job.conf # and ensure $SEATUNNEL_HOME/connectors contains the jars
Defensive patterns
Strategy: validation
Validate before calling
import os
from pathlib import Path
plugin_dir = Path(os.environ.get('SEATUNNEL_HOME', '.'), 'connectors')
if not plugin_dir.is_dir():
raise SystemExit(f'Plugin dir missing or not a directory: {plugin_dir}')
if not any(plugin_dir.glob('*.jar')):
raise SystemExit(f'No connector jars found in: {plugin_dir}') Type guard
def plugin_dir_ok(path):
p = Path(path)
return p.is_dir() and os.access(p, os.R_OK) Prevention
- Always run sh bin/install-plugin.sh after installing SeaTunnel
- Verify SEATUNNEL_HOME points to the actual install root
- Check dir readability under the user running the engine
- Keep connector jars in the default $SEATUNNEL_HOME/connectors location
When it happens
Trigger: getPluginFactories() is invoked (via factories) while FileUtils.searchJarFiles(this.pluginDir) throws IOException — typically the plugin dir path is a file, unreadable, or an I/O error occurs while walking it.
Common situations: SEATUNNEL_HOME misconfigured so connector-plugin points at a non-directory or unreadable path; connectors directory deleted or permission-restricted; network/ACL-mounted plugin dir unavailable at runtime.
Related errors
- Cannot find unique plugin jar for pluginIdentifier: %s -> %s
- Stream closed
- Failed to close Google Pub/Sub publisher
- maxLines must be >= 1
- Plugin %s not found.
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/c3bfbe5bbfe8542e.
Report an issue: GitHub.