{"record":{"id":"92d0ddc9814ab29b","repo":"apache/seatunnel","slug":"unable-to-create-a-source-for-identifier-factor","errorCode":null,"errorMessage":"Unable to create a source for identifier '${factoryIdentifier}'.","messagePattern":"Unable to create a source for identifier '(.+?)'\\.","errorType":"exception","errorClass":"FactoryException","httpStatus":null,"severity":"error","filePath":"seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java","lineNumber":176,"sourceCode":"                        CatalogTableUtil.convertDataTypeToCatalogTables(seaTunnelDataType, tableId);\n            }\n            LOG.info(\n                    \"get the CatalogTable from source {}: {}\",\n                    source.getPluginName(),\n                    catalogTables.stream()\n                            .map(CatalogTable::getTableId)\n                            .map(TableIdentifier::toString)\n                            .collect(Collectors.joining(\",\")));\n            if (options.get(SourceConnectorCommonOptions.DAG_PARSING_MODE)\n                    == ParsingMode.SHARDING) {\n                CatalogTable catalogTable = catalogTables.get(0);\n                catalogTables.clear();\n                catalogTables.add(catalogTable);\n            }\n            return new Tuple2<>(source, catalogTables);\n\n        } catch (Throwable t) {\n            throw new FactoryException(\n                    String.format(\n                            \"Unable to create a source for identifier '%s'.\", factoryIdentifier),\n                    t);\n        }\n    }\n\n    private static <T, SplitT extends SourceSplit, StateT extends Serializable>\n            SeaTunnelSource<T, SplitT, StateT> createAndPrepareSource(\n                    TableSourceFactory factory,\n                    ReadonlyConfig options,\n                    ClassLoader classLoader,\n                    MetadataConfig metaDataConfig) {\n        TableSourceFactoryContext context =\n                new TableSourceFactoryContext(options, classLoader, metaDataConfig);\n        ConfigValidator.of(context.getOptions()).validate(factory.optionRule());\n        TableSource<T, SplitT, StateT> tableSource = factory.createSource(context);\n        return tableSource.createSource();\n    }","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java#L158-L194","documentation":"FactoryUtil.restoreAndPrepareSource wraps any Throwable raised while discovering, instantiating, or preparing a Source in a FactoryException with this message. It is a wrapper: the real cause (attached as the cause) explains what actually failed.","triggerScenarios":"Calling FactoryUtil.createAndPrepareSource with a factory identifier whose Source plugin is missing, whose factory throws in its constructor/prepare(), whose options fail validation, or whose catalog table conversion fails.","commonSituations":"Typo in the source plugin name in the job config; connector jar not installed in $SEATUNNEL_HOME/connectors; connector throws during prepare() because of bad credentials or missing files.","solutions":["Read the 'Caused by' of the FactoryException — it contains the real failure.","Verify the factory identifier matches a Source plugin in the connectors directory (check plugin-mapping.properties).","Install the missing connector: sh bin/install-plugin.sh <version>.","Validate source options against the connector's documented option rule (missing required options fail in this path)."],"exampleFix":"// before\nsource {\n  MySql-CDC-Jdbc {}\n}\n// after\nsource {\n  JDBC {\n    url = \"jdbc:mysql://localhost:3306/db\"\n  }\n}","handlingStrategy":"try-catch","validationCode":"Optional<TableSourceFactory> f = FactoryUtil.discoverOptionalSourceFactory(classLoader, pluginId);\nif (!f.isPresent()) {\n    throw new IllegalArgumentException(\"Source plugin not installed: \" + pluginId);\n}","typeGuard":null,"tryCatchPattern":"try {\n    Tuple2<SeaTunnelSource, List<CatalogTable>> t = FactoryUtil.createAndPrepareSource(cfg, classLoader, pluginId);\n} catch (FactoryException e) {\n    LOG.error(\"Source '{}' creation failed\", pluginId, e.getCause()); // cause holds the real error\n    throw e;\n}","preventionTips":["Validate source options with ConfigValidator against the factory's optionRule before creating.","Keep connector jars in $SEATUNNEL_HOME/connectors and keep plugin-mapping.properties current.","Always log e.getCause() when handling FactoryException from createAndPrepareSource."],"tags":["factory","spi","source-plugin","wrapper"],"backgroundTag":"resource-not-found","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}