apache/seatunnel · error · ClickhouseConnectorException
QUERY_TABLE_NOT_SUPPORT_NON_MERGE_TREE_TABLE
QUERY_TABLE_NOT_SUPPORT_NON_MERGE_TREE_TABLE
Error message
Query table mode not support non-MergeTree local table. Please specify sql parameter in configuration
What it means
In query-table mode with no explicit sql, ClickhouseSourceSplitEnumerator.getClusterShardList() requires the local (non-distributed) table engine to be a MergeTree family engine so it can derive shard/parallel read ranges. Non-MergeTree local tables (e.g. Log, Memory, external engines) cannot be split this way, so the connector throws QUERY_TABLE_NOT_SUPPORT_NON_MERGE_TREE_TABLE.
Solutions
- Set the `sql` option in the ClickHouse source config to supply your own query, bypassing MergeTree-based split enumeration.
- Use a MergeTree-family local table (or change the underlying table engine) if table-mode reading is required.
- Verify the table/database names resolve to the intended MergeTree table.
- If the table is Distributed, confirm its local table (system.tables.engine for the inner table) is MergeTree family.
Example fix
// before: config without sql
source {
Clickhouse {
url = "jdbc:clickhouse://localhost:8123"
database = "default"
table = "my_log_table"
}
}
// after: provide sql explicitly
source {
Clickhouse {
url = "jdbc:clickhouse://localhost:8123"
sql = "SELECT * FROM default.my_log_table"
}
} Defensive patterns
Strategy: validation
Validate before calling
// Before submitting, check local table engine SELECT engine FROM system.tables WHERE database = 'default' AND name = 'my_table'; // must contain 'MergeTree' or config must define `sql`
Try / catch
try {
runJob(config);
} catch (ClickhouseConnectorException e) {
if (e.getSeaTunnelErrorCode() == ClickhouseConnectorErrorCode.QUERY_TABLE_NOT_SUPPORT_NON_MERGE_TREE_TABLE) {
// resubmit with `sql` option set
} else throw e;
} Prevention
- Always provide `sql` in table mode unless the table is MergeTree family.
- Check engine via system.tables before configuring table mode.
- Remember Distributed tables depend on their local table's engine, not their own.
- Keep table names exact; wrong names can resolve to non-MergeTree tables.
When it happens
Trigger: clickhouse source config has no `sql` option, table not distributed (or distributed whose local table engine string doesn't contain "MergeTree"), and localTableEngine.contains("MergeTree") is false at ClickhouseSourceSplitEnumerator.java:261.
Common situations: Pointing the connector at a Log/Memory/Kafka-engine table; Distributed table whose local table is non-MergeTree; typo'd table name resolving to an unexpected table; older ClickHouse engine naming (e.g. 'ReplicatedMergeTree' works, but 'StripeLog' doesn't).
Related errors
- part size is less than , set to default value
- Agent config file not found
- AmazonDocumentDB option '' must be a valid BSON/JSON…
- AmazonDocumentDB option '' must not be blank
- AmazonDocumentDB option 'tls_ca_file' is required when TLS…
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/e79c8e4e745736fe.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-clickhouse/src/main/java/org/apache/seatunnel/connectors/seatunnel/clickhouse/source/split/ClickhouseSourceSplitEnumerator.java:261
clusterShardList =
proxy.getClusterShardList(
proxy.getClickhouseConnection(),
distributedEngine.getClusterName(),
distributedEngine.getDatabase(),
nodes.get(0).getPort(),
clickhouseSourceConfig.getUsername(),
clickhouseSourceConfig.getPassword(),
nodes.get(0).getOptions());
} else {
// if input is local table, generate shard list based on the input nodes
clusterShardList = buildClusterShardFromNodes(nodes);
localTableEngine = clickhouseTable.getEngine();
}
if (StringUtils.isEmpty(clickhouseSourceTable.getOriginQuery())
&& !localTableEngine.contains("MergeTree")) {
throw new ClickhouseConnectorException(
ClickhouseConnectorErrorCode.QUERY_TABLE_NOT_SUPPORT_NON_MERGE_TREE_TABLE,
"Query table mode not support non-MergeTree local table. Please specify sql parameter in configuration");
}
return clusterShardList;
}
}
private List<Shard> buildClusterShardFromNodes(List<ClickHouseNode> nodes) {
List<Shard> shards = new ArrayList<>();
IntStream.range(0, nodes.size())
.forEach(
i -> {
ClickHouseNode node = nodes.get(i);
Shard shard = new Shard(i, 1, node);
shards.add(shard);
});
View on GitHub (pinned to cf67b549a7)