{"record":{"id":"404a5437dc7bab35","repo":"apache/seatunnel","slug":"no-suitable-dialect-factory","errorCode":"NO_SUITABLE_DIALECT_FACTORY","errorMessage":"Could not find any jdbc dialect factories that implement '%s' in the classpath.","messagePattern":"Could not find any jdbc dialect factories that implement '(.+?)' in the classpath\\.","errorType":"error_code","errorClass":"JdbcConnectorException","httpStatus":null,"severity":"critical","filePath":"seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/JdbcDialectLoader.java","lineNumber":85,"sourceCode":"     * Loads the unique JDBC Dialect that can handle the given database url.\n     *\n     * @param url A database URL.\n     * @param compatibleMode The compatible mode.\n     * @return The loaded dialect.\n     * @throws IllegalStateException if the loader cannot find exactly one dialect that can\n     *     unambiguously process the given database URL.\n     */\n    public static JdbcDialect load(\n            String url,\n            String compatibleMode,\n            String dialect,\n            String fieldIde,\n            JdbcConnectionConfig jdbcConnectionConfig) {\n        ClassLoader cl = Thread.currentThread().getContextClassLoader();\n        List<JdbcDialectFactory> foundFactories = discoverFactories(cl);\n\n        if (foundFactories.isEmpty()) {\n            throw new JdbcConnectorException(\n                    JdbcConnectorErrorCode.NO_SUITABLE_DIALECT_FACTORY,\n                    String.format(\n                            \"Could not find any jdbc dialect factories that implement '%s' in the classpath.\",\n                            JdbcDialectFactory.class.getName()));\n        }\n        List<JdbcDialectFactory> matchingFactories;\n        if (dialect != null) {\n            matchingFactories =\n                    foundFactories.stream()\n                            .filter(f -> f.dialectFactoryName().equalsIgnoreCase(dialect))\n                            .collect(Collectors.toList());\n        } else {\n            matchingFactories =\n                    foundFactories.stream()\n                            .filter(f -> f.acceptsURL(url))\n                            .collect(Collectors.toList());\n        }\n","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/JdbcDialectLoader.java#L67-L103","documentation":"JdbcDialectLoader.load() discovers JDBC dialect factories via Java ServiceLoader; when the discovered factory list is empty it throws this JdbcConnectorException with code NO_SUITABLE_DIALECT_FACTORY. It means no META-INF/services/org.apache.seatunnel...JdbcDialectFactory provider file (and hence no dialect implementation) is present on the thread-context classpath.","triggerScenarios":"Calling JdbcDialectLoader.load(...) with a context classloader whose classpath contains no JdbcDialectFactory service providers — e.g. connector-jdbc jar(s) not installed, no connector jar deployed to the plugins directory, or a fat/classloader-isolation setup that hides META-INF/services entries.","commonSituations":"Forgetting to run install-plugin.sh or otherwise not deploying connector-jdbc jars to the Zeta engine's connectors directory; building a minimal distribution without any jdbc dialect module; custom classloader (e.g. inside another framework) that does not expose the service files; shading/assembly plugin stripping META-INF/services.","solutions":["Install/deploy the connector-jdbc plugin jars (sh bin/install-plugin.sh <version> or copy the connector-jdbc + target dialect jar into $SEATUNNEL_HOME/connectors)","Verify META-INF/services/org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.JdbcDialectFactory exists inside the deployed jar","Check Thread.currentThread().getContextClassLoader() is correct when invoking load() from embedded/custom classloader code","If building a shaded jar, configure ServiceResourceTransformer so META-INF/services files are merged, not dropped"],"exampleFix":"// before: classpath has no jdbc connector jar\njava -cp app.jar com.example.SeaTunnelJob   # -> NO_SUITABLE_DIALECT_FACTORY\n// after: include connector-jdbc and dialect jars on classpath / plugins dir\n# copy seatunnel-connectors-v2/connector-jdbc/target/connector-jdbc-*.jar\n# and the dialect jar (e.g. mysql driver + factory) into $SEATUNNEL_HOME/connectors/\nsh bin/install-plugin.sh 2.3.x","handlingStrategy":"validation","validationCode":"// before calling load, ensure at least one factory is discoverable\nClassLoader cl = Thread.currentThread().getContextClassLoader();\nif (!cl.getResources(\"META-INF/services/org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.JdbcDialectFactory\").hasMoreElements()) {\n  throw new IllegalStateException(\"connector-jdbc dialect factories not on classpath\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  JdbcDialect dialect = JdbcDialectLoader.load(url, ...);\n} catch (JdbcConnectorException e) {\n  if (e.getCode() == JdbcConnectorErrorCode.NO_SUITABLE_DIALECT_FACTORY) {\n    log.error(\"No JDBC dialect factory on classpath; deploy connector-jdbc jars first\");\n  }\n  throw e;\n}","preventionTips":["Always run sh bin/install-plugin.sh <version> or copy connector-jdbc jars into $SEATUNNEL_HOME/connectors","Verify jar contains META-INF/services entry for JdbcDialectFactory after custom builds","Use a shading ServiceResourceTransformer so services files survive fat-jar assembly","Check Thread.currentThread().getContextClassLoader() when loading dialects from embedded code"],"tags":["jdbc","serviceloader","classpath","dialect"],"backgroundTag":"missing-dependency","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}