{"record":{"id":"81ed85da758b030d","repo":"apache/seatunnel","slug":"config-validation-failed-81ed85","errorCode":"CONFIG_VALIDATION_FAILED","errorMessage":"PluginName: %s, PluginType: %s, Message: %s","messagePattern":"PluginName: (.+?), PluginType: (.+?), Message: (.+?)","errorType":"error_code","errorClass":"IcebergConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-iceberg/src/main/java/org/apache/seatunnel/connectors/seatunnel/iceberg/sink/IcebergSink.java","lineNumber":118,"sourceCode":"    @Override\n    public Optional<Serializer<IcebergAggregatedCommitInfo>> getAggregatedCommitInfoSerializer() {\n        return Optional.of(new DefaultSerializer<>());\n    }\n\n    @Override\n    public Optional<Serializer<IcebergCommitInfo>> getCommitInfoSerializer() {\n        return Optional.of(new DefaultSerializer<>());\n    }\n\n    @Override\n    public Optional<SaveModeHandler> getSaveModeHandler() {\n        CatalogFactory catalogFactory =\n                discoverFactory(\n                        Thread.currentThread().getContextClassLoader(),\n                        CatalogFactory.class,\n                        \"Iceberg\");\n        if (catalogFactory == null) {\n            throw new IcebergConnectorException(\n                    SeaTunnelAPIErrorCode.CONFIG_VALIDATION_FAILED,\n                    String.format(\n                            \"PluginName: %s, PluginType: %s, Message: %s\",\n                            getPluginName(), PluginType.SINK, \"Cannot find Doris catalog factory\"));\n        }\n        Catalog catalog =\n                catalogFactory.createCatalog(catalogFactory.factoryIdentifier(), readonlyConfig);\n        return Optional.of(\n                new DefaultSaveModeHandler(\n                        config.getSchemaSaveMode(),\n                        config.getDataSaveMode(),\n                        catalog,\n                        catalogTable,\n                        config.getDataSaveModeSQL()));\n    }\n\n    @Override\n    public Optional<CatalogTable> getWriteCatalogTable() {","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-iceberg/src/main/java/org/apache/seatunnel/connectors/seatunnel/iceberg/sink/IcebergSink.java#L100-L136","documentation":"IcebergSink.getSaveModeHandler throws IcebergConnectorException with CONFIG_VALIDATION_FAILED when the 'Iceberg' CatalogFactory SPI cannot be discovered. The message text mentions Doris catalog factory, but the actual trigger is the missing Iceberg catalog factory plugin. This typically means the Iceberg connector jar is absent from the plugin directory so the SPI cannot load.","triggerScenarios":"Calling getSaveModeHandler (during sink initialization with save-mode enabled) when discoverFactory(..., CatalogFactory.class, \"Iceberg\") returns null because no provider registers the 'Iceberg' catalog factory identifier.","commonSituations":"Iceberg connector jar missing from $SEATUNNEL_HOME/connectors; install-plugin.sh not run or connector not downloaded; mixed SeaTunnel versions where connector jar version mismatches the engine; classloader isolation hiding the SPI file.","solutions":["Ensure seatunnel-connector-connector-iceberg jar exists in $SEATUNNEL_HOME/connectors (run sh bin/install-plugin.sh).","Verify connector-catalog 'Iceberg' identifier matches your SeaTunnel version; align connector and engine versions.","Check plugin discovery config (seatunnel.yaml plugin-discovery / connector classloader settings).","Confirm META-INF/services registration for CatalogFactory is present in the iceberg jar (jar not corrupted/partially copied)."],"exampleFix":"// before (missing jar)\n$SEATUNNEL_HOME/connectors/  # no connector-iceberg jar\n// after\nsh bin/install-plugin.sh 2.3.x\nls $SEATUNNEL_HOME/connectors/connector-iceberg-2.3.x.jar","handlingStrategy":"validation","validationCode":"// before starting the job, verify the Iceberg connector jar is present\njava.nio.file.Path connectors = java.nio.file.Path.of(System.getenv(\"SEATUNNEL_HOME\"), \"connectors\");\nboolean icebergPresent = java.nio.file.Files.list(connectors).anyMatch(p -> p.getFileName().toString().startsWith(\"connector-iceberg-\"));\nif (!icebergPresent) throw new IllegalStateException(\"Iceberg connector jar missing; run sh bin/install-plugin.sh\");","typeGuard":null,"tryCatchPattern":"try { sink.openPrepare(); } catch (IcebergConnectorException e) { if (e.getSeaTunnelApiErrorCode() == SeaTunnelAPIErrorCode.CONFIG_VALIDATION_FAILED) { log.error(\"Iceberg catalog factory not found; install connector-iceberg jar\"); } throw e; }","preventionTips":["Run sh bin/install-plugin.sh after installing/upgrading SeaTunnel","Keep connector jar versions identical to the engine version","Verify META-INF/services CatalogFactory registration exists in the iceberg jar","Check classloader/plugin-discovery settings in seatunnel.yaml when using custom deployments"],"tags":["iceberg","sink","plugin-discovery","spi","config-validation"],"backgroundTag":"class-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"}