{"record":{"id":"9be63e16cd4d16f1","repo":"apache/dolphinscheduler","slug":"duplicate-datasource-processor-named-s","errorCode":null,"errorMessage":"Duplicate datasource processor named '%s'","messagePattern":"Duplicate datasource processor named '(.+?)'","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-api/src/main/java/org/apache/dolphinscheduler/plugin/datasource/api/plugin/DataSourcePluginManager.java","lineNumber":84,"sourceCode":"                (dataSourceChannelName, dataSourceChannelFactory) -> {\n                    if (datasourceChannelMap.containsKey(dataSourceChannelName)) {\n                        throw new IllegalStateException(\n                                format(\"Duplicate datasource channel named '%s'\", dataSourceChannelName));\n                    }\n                    datasourceChannelMap.put(dataSourceChannelName, dataSourceChannelFactory.create());\n                    log.info(\"Registered datasource channel: {}\", dataSourceChannelName);\n                });\n    }\n\n    private static synchronized void initializeDataSourceProcessor() {\n        if (MapUtils.isNotEmpty(dataSourceProcessorMap)) {\n            return;\n        }\n\n        ServiceLoader.load(DataSourceProcessor.class).forEach(factory -> {\n            final String name = factory.getDbType().getName();\n            if (dataSourceProcessorMap.containsKey(name)) {\n                throw new IllegalStateException(format(\"Duplicate datasource processor named '%s'\", name));\n            }\n            DataSourceProcessor dataSourceProcessor = factory.create();\n            dataSourceProcessorMap.put(name, dataSourceProcessor);\n            log.info(\"Success register datasource processor -> {}\", name);\n        });\n    }\n\n}\n","sourceCodeStart":66,"sourceCodeEnd":93,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-api/src/main/java/org/apache/dolphinscheduler/plugin/datasource/api/plugin/DataSourcePluginManager.java#L66-L93","documentation":"Thrown by DataSourcePluginManager when ServiceLoader discovers two DataSourceProcessor implementations whose getDbType() returns the same database type name. Since processors are stored in a map keyed by DbType name, a duplicate would be ambiguous, so initialization fails fast. This is a plugin packaging / classpath conflict.","triggerScenarios":"loadDataSourcePlugin -> initializeDataSourceProcessor encountering two jars that register a DataSourceProcessor for the same DbType via java.util.ServiceLoader, or the same processor class loaded twice.","commonSituations":"Custom datasource plugin extending an existing processor (e.g. subclassing MysqlDataSourceProcessor) without overriding getDbType(); duplicate plugin jars after upgrade; shaded uber-jar merging service descriptors.","solutions":["Identify jars containing META-INF/services/org.apache.dolphinscheduler.spi.datasource.DataSourceProcessor entries and find the duplicated DbType","Remove duplicate/stale processor jars from the plugin/lib classpath","In your custom processor, override getDbType() to return a distinct DbType, or do not extend a processor whose DbType is already registered","Deduplicate META-INF/services files when building an uber-jar (shade ServicesResourceTransformer)"],"exampleFix":"// before\nclass MyPostgresProcessor extends PostgresDataSourceProcessor {\n  // inherits getDbType() -> POSTGRES, duplicate registration\n}\n// after\n@Override\npublic DbType getDbType() { return DbType.MY_POSTGRES; }","handlingStrategy":"try-catch","validationCode":"Map<String,Integer> counts = new HashMap<>();\nServiceLoader.load(DataSourceProcessor.class).forEach(p -> counts.merge(p.getDbType().getName(), 1, Integer::sum));\ncounts.entrySet().stream().filter(e -> e.getValue() > 1).forEach(e -> System.out.println(\"duplicate: \" + e));","typeGuard":"if (dataSourceProcessorMap.containsKey(name)) { log.warn(\"processor {} already registered, skipping\", name); return; }","tryCatchPattern":"try {\n  pluginManager.loadDataSourcePlugin();\n} catch (IllegalStateException e) {\n  if (e.getMessage().startsWith(\"Duplicate datasource processor\")) {\n    log.error(\"Duplicate DataSourceProcessor DbType: {}\", e.getMessage());\n  } else throw e;\n}","preventionTips":["Always override getDbType() when extending an existing processor","Avoid shipping two jars containing processors for the same DbType","Merge service files in uber-jars","Audit META-INF/services after dependency changes"],"tags":["spi","service-loader","duplicate-name","plugin-registration"],"backgroundTag":"duplicate-plugin-registration","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}