{"record":{"id":"febafcb9f13c68fe","repo":"apache/seatunnel","slug":"plugin-dir-not-exists-load-plugin-from-classp","errorCode":null,"errorMessage":"plugin dir: {} not exists, load plugin from classpath","messagePattern":"plugin dir: (.+?) not exists, load plugin from classpath","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-plugin-discovery/src/main/java/org/apache/seatunnel/plugin/discovery/AbstractPluginDiscovery.java","lineNumber":385,"sourceCode":"    }\n\n    protected List<Factory> getPluginFactories() {\n        List<Factory> factories;\n        if (this.pluginDir.toFile().exists()) {\n            log.debug(\"load plugin from plugin dir: {}\", this.pluginDir);\n            List<URL> files;\n            try {\n                files = FileUtils.searchJarFiles(this.pluginDir);\n            } catch (IOException e) {\n                throw new RuntimeException(\n                        String.format(\n                                \"Can not find any plugin(source/sink/transform) in the dir: %s\",\n                                this.pluginDir));\n            }\n            factories =\n                    FactoryUtil.discoverFactories(new URLClassLoader(files.toArray(new URL[0])));\n        } else {\n            log.warn(\"plugin dir: {} not exists, load plugin from classpath\", this.pluginDir);\n            factories =\n                    FactoryUtil.discoverFactories(Thread.currentThread().getContextClassLoader());\n        }\n        return factories;\n    }\n\n    protected T loadPluginInstance(PluginIdentifier pluginIdentifier, ClassLoader classLoader) {\n        ServiceLoader<T> serviceLoader = ServiceLoader.load(getPluginBaseClass(), classLoader);\n        for (T t : serviceLoader) {\n            if (t instanceof PluginIdentifierInterface) {\n                // new api\n                PluginIdentifierInterface pluginIdentifierInstance = (PluginIdentifierInterface) t;\n                if (StringUtils.equalsIgnoreCase(\n                        pluginIdentifierInstance.getPluginName(),\n                        pluginIdentifier.getPluginName())) {\n                    return (T) pluginIdentifierInstance;\n                }\n            } else {","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-plugin-discovery/src/main/java/org/apache/seatunnel/plugin/discovery/AbstractPluginDiscovery.java#L367-L403","documentation":"getPluginFactories expects the configured plugin directory (e.g., connectors/) to exist so it can build a URLClassLoader over its jars. If the directory does not exist, it logs this warning and instead discovers factories from the thread context classpath, which usually contains only core classes — typically leading to 'plugin not found' errors later.","triggerScenarios":"The pluginDir passed to AbstractPluginDiscovery (derived from SEATUNNEL_HOME/connectors or a -Dplugin config) does not exist on the node starting the job.","commonSituations":"SEATUNNEL_HOME not set or wrong on a cluster node; connector never installed (install-plugin.sh not run); running from IDE/source without connectors dir; fat-jar deployment without plugin dirs.","solutions":["Set SEATUNNEL_HOME correctly on every node so the connectors/ dir resolves","Run sh bin/install-plugin.sh <version> to download connector jars into the plugin dir","If you intentionally ship connectors on the classpath, confirm the connector jar is inside lib/ or the app classpath","Verify the plugin dir path in your config/CLI (e.g., --name uses correct connector identifier once dir exists)"],"exampleFix":"// before: missing dir\nexport SEATUNNEL_HOME=/opt/seatunnel  # connectors/ absent\n// after\nsh bin/install-plugin.sh 2.3.x\nls $SEATUNNEL_HOME/connectors/connector-console-*.jar","handlingStrategy":"validation","validationCode":"File pluginDir = new File(System.getenv(\"SEATUNNEL_HOME\"), \"connectors\");\nif (!pluginDir.isDirectory()) throw new IllegalStateException(\"install connectors: \" + pluginDir);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set SEATUNNEL_HOME on every cluster node","Run install-plugin.sh before first job","Keep connector jars on classpath if running plugin-less","Check dir path after upgrades/migrations"],"tags":["plugin-discovery","classpath","configuration"],"backgroundTag":"directory-not-found","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}