apache/seatunnel · error · FactoryException
Unable to create a sink for identifier 'MultiTableSink'.
Error message
Unable to create a sink for identifier 'MultiTableSink'.
What it means
FactoryUtil.createMultiTableSink wraps any Throwable raised while creating the built-in MultiTableSink (used to write to multiple tables) in a FactoryException. The hard-coded identifier 'MultiTableSink' is always present, so failure is almost always inside the factory's option validation or createSink() call.
Source
Thrown at seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java:282
"Unable to create a sink for identifier '%s'.", factoryIdentifier),
t);
}
}
public static <IN, StateT, CommitInfoT, AggregatedCommitInfoT>
SeaTunnelSink<IN, StateT, CommitInfoT, AggregatedCommitInfoT> createMultiTableSink(
Map<TablePath, SeaTunnelSink> sinks,
ReadonlyConfig options,
ClassLoader classLoader) {
try {
TableSinkFactory<IN, StateT, CommitInfoT, AggregatedCommitInfoT> factory =
new MultiTableSinkFactory();
MultiTableFactoryContext context =
new MultiTableFactoryContext(options, classLoader, sinks);
ConfigValidator.of(context.getOptions()).validate(factory.optionRule());
return factory.createSink(context).createSink();
} catch (Throwable t) {
throw new FactoryException(
"Unable to create a sink for identifier 'MultiTableSink'.", t);
}
}
public static Optional<Catalog> createOptionalCatalog(
String catalogName,
ReadonlyConfig readonlyConfig,
ClassLoader classLoader,
String factoryIdentifier) {
Optional<CatalogFactory> optionalFactory =
discoverOptionalFactory(classLoader, CatalogFactory.class, factoryIdentifier);
return optionalFactory.map(
catalogFactory -> {
ConfigValidator.of(readonlyConfig).validate(catalogFactory.optionRule());
return catalogFactory.createCatalog(catalogName, readonlyConfig);
});
}View on GitHub (pinned to cf67b549a7)
Solutions
- Examine the wrapped cause for the exact option-validation or creation error.
- Check the multi-table sink options against MultiTableSinkFactory's option rule.
- Ensure the underlying sink instances passed in were created successfully.
Example fix
// before
Map<String, Object> opts = new HashMap<>(); // empty, fails validation
// after
Map<String, Object> opts = new HashMap<>();
opts.put("multi_table_sink.fields_change", "EXCEPT"); // options matching the option rule Defensive patterns
Strategy: try-catch
Validate before calling
ConfigValidator.of(options).validate(new MultiTableSinkFactory().optionRule()); // run before createMultiTableSink
Try / catch
try {
sink = FactoryUtil.createMultiTableSink(options, classLoader, sinks);
} catch (FactoryException e) {
LOG.error("MultiTableSink creation failed", e.getCause());
throw e;
} Prevention
- Run ConfigValidator with MultiTableSinkFactory.optionRule() before creating.
- Ensure each underlying sink was already created successfully.
- Use the application classloader that can see all connector classes.
When it happens
Trigger: Calling FactoryUtil.createMultiTableSink(options, classLoader, sinks) when ConfigValidator rejects the supplied options or the MultiTableSinkFactory.createSink() throws while wrapping the underlying sinks.
Common situations: Invalid multi-table sink options in the job config; underlying sink list contains misconfigured sinks; classloader issues in SeaTunnel Web/cluster deployments.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Unable to create a source for identifier '${factoryIdentifie
- Unable to create a sink for identifier '${factoryIdentifier}
- Could not find any factories that implement '%s' in the clas
- Could not find any factory for identifier '%s' that implemen
- Multiple factories for identifier '%s' that implement '%s' f
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/6c2d88a3cfd238a3.
Report an issue: GitHub.