apache/seatunnel · error · FileConnectorException
CONFIG_VALIDATION_FAILED
CONFIG_VALIDATION_FAILED
Error message
In multi-table mode, option 'discovery_mode' must be consistent across tables.
What it means
BaseMultipleTableFileSource.resolveDiscoveryMode requires every table's config to use the same discovery_mode. When the first table's DISCOVERY_MODE differs from any other table's, it throws CONFIG_VALIDATION_FAILED telling you the option must be consistent across tables.
Source
Thrown at seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/source/BaseMultipleTableFileSource.java:170
tableIds.add(config.getCatalogTable().getTableId().toTablePath().toString());
}
}
return tableIds;
}
private FileDiscoveryMode resolveDiscoveryMode() {
List<BaseFileSourceConfig> configs =
baseMultipleTableFileSourceConfig.getFileSourceConfigs();
if (configs == null || configs.isEmpty()) {
return FileDiscoveryMode.ONCE;
}
FileDiscoveryMode mode =
configs.get(0).getBaseFileSourceConfig().get(FileBaseSourceOptions.DISCOVERY_MODE);
for (BaseFileSourceConfig config : configs) {
FileDiscoveryMode currentMode =
config.getBaseFileSourceConfig().get(FileBaseSourceOptions.DISCOVERY_MODE);
if (currentMode != mode) {
throw new FileConnectorException(
SeaTunnelAPIErrorCode.CONFIG_VALIDATION_FAILED,
"In multi-table mode, option '"
+ FileBaseSourceOptions.DISCOVERY_MODE.key()
+ "' must be consistent across tables.");
}
}
if (mode != FileDiscoveryMode.CONTINUOUS) {
for (BaseFileSourceConfig config : configs) {
FilePostSyncAction action =
config.getBaseFileSourceConfig()
.get(FileBaseSourceOptions.POST_SYNC_ACTION);
if (action == FilePostSyncAction.NONE) {
continue;
}
throw new FileConnectorException(
SeaTunnelAPIErrorCode.CONFIG_VALIDATION_FAILED,
"post_sync_action only supports discovery_mode=continuous. "
+ "Please set post_sync_action=none or switch discovery_mode to continuous.");View on GitHub (pinned to cf67b549a7)
Solutions
- Set the same discovery_mode in every table's base file source config.
- Decide the job's boundedness (batch vs streaming) first, then apply one mode to all tables.
- Search all table configs for `discovery_mode` and normalize them.
- Resubmit; the check runs again on getBoundedness/createEnumerator.
Example fix
// before table1: discovery_mode = continuous table2: discovery_mode = create_once // after table1: discovery_mode = continuous table2: discovery_mode = continuous
Defensive patterns
Strategy: validation
Validate before calling
Set<String> modes = tableConfigs.stream()
.map(c -> c.getString("discovery_mode"))
.collect(Collectors.toSet());
if (modes.size() > 1) {
throw new IllegalArgumentException("All tables must share one discovery_mode, got: " + modes);
} Try / catch
try {
// create multi-table source
} catch (FileConnectorException e) {
if (SeaTunnelAPIErrorCode.CONFIG_VALIDATION_FAILED.equals(e.getErrorCode())
&& e.getMessage().contains("discovery_mode")) {
throw new IllegalStateException("Normalize discovery_mode across all table configs", e);
}
throw e;
} Prevention
- Generate multi-table configs from one template with a single discovery_mode variable.
- Grep generated configs for discovery_mode drift before submission.
- Document that boundedness is job-level, not per-table.
When it happens
Trigger: A multi-table file source (multiple tables/paths configured) where at least one table sets discovery_mode (e.g. `create_once`) differently from the first table (e.g. `continuous`); resolveDiscoveryMode is invoked by getBoundedness, createEnumerator, and restoreEnumerator.
Common situations: Merging per-table config files with different discovery_mode values; adding a new table entry copied from a batch job into a streaming job; typo making one table fall back to a different default.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- plugin_input must not be empty when configured
- Schema config can not be empty
- Unknown format type:
- Option '${option}' cannot be blank
- Option '${valuesAndOptions[index + 1]}' is not valid for the
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/6a2629472d7f4490.
Report an issue: GitHub.