apache/seatunnel · error · FactoryException
sinkOptionRule can not be null
Error message
sinkOptionRule can not be null
What it means
FactoryUtil.sinkFullOptionRule throws this FactoryException when the given TableSinkFactory's optionRule() returns null. Like the source variant, a null rule means the factory does not satisfy the API contract of exposing its configuration options.
Solutions
- Implement optionRule() in the TableSinkFactory returning a non-null OptionRule.
- Upgrade the sink connector to a release that declares its option rule.
- Return an empty OptionRule if the sink truly has no user options.
Example fix
// before
@Override
public OptionRule optionRule() { return null; }
// after
@Override
public OptionRule optionRule() {
return OptionRule.builder().required(SinkOptions.JDBC_URL).build();
} Defensive patterns
Strategy: type-guard
Validate before calling
OptionRule rule = factory.optionRule();
if (rule == null) {
throw new IllegalStateException(factory.factoryIdentifier() + " must implement optionRule()");
} Type guard
boolean hasValidOptionRule(TableSinkFactory f) { return f.optionRule() != null; } Try / catch
try {
return FactoryUtil.sinkFullOptionRule(factory);
} catch (FactoryException e) {
throw new IllegalStateException("Sink connector must declare a non-null OptionRule", e);
} Prevention
- Implement optionRule() in every custom TableSinkFactory.
- Add a test asserting optionRule() is non-null for each sink connector.
- Pin sink connector versions known to declare option rules.
When it happens
Trigger: Calling FactoryUtil.sinkFullOptionRule(factory) with a sink factory whose optionRule() is unimplemented or explicitly returns null — typical of custom or legacy connectors.
Common situations: Custom sink connector under development missing optionRule(); third-party sink jar built against an older API; copying a sink skeleton that left optionRule() returning null.
Related errors
- sourceOptionRule can not be null
- Could not find any factories that implement
- Could not find any factory for identifier
- Multiple factories for identifier
- SeaTunnelAPIErrorCode.CONFIG_VALIDATION_FAILED
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/ce7a0f0f6a8f0791.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java:447
OptionRule sourceCommonOptionRule =
OptionRule.builder().optional(EnvCommonOptions.PARALLELISM).build();
sourceOptionRule
.getOptionalOptions()
.addAll(sourceCommonOptionRule.getOptionalOptions());
}
return sourceOptionRule;
}
/**
* This method is called by SeaTunnel Web to get the full option rule of a sink.
*
* @return Option rule
*/
public static OptionRule sinkFullOptionRule(@NonNull TableSinkFactory factory) {
OptionRule sinkOptionRule = factory.optionRule();
if (sinkOptionRule == null) {
throw new FactoryException("sinkOptionRule can not be null");
}
return sinkOptionRule;
}
public static SeaTunnelTransform<?> createAndPrepareMultiTableTransform(
List<CatalogTable> catalogTables,
ReadonlyConfig options,
ClassLoader classLoader,
String factoryIdentifier) {
final TableTransformFactory factory =
discoverFactory(classLoader, TableTransformFactory.class, factoryIdentifier);
TableTransformFactoryContext context =
new TableTransformFactoryContext(catalogTables, options, classLoader);
ConfigValidator.of(context.getOptions()).validate(factory.optionRule());
return factory.createTransform(context).createTransform();
}
private static <T extends Factory> boolean isFallback(View on GitHub (pinned to cf67b549a7)