Type of problem
Code bug — currentDatabase() is not resolved at CREATE TABLE time in the Hybrid engine, causing every server restart to fail with UNKNOWN_TABLE when the table was created in a non-default database.
Because of it now stress test fails on every pr (exmaple https://altinity-build-artifacts.s3.amazonaws.com/json.html?PR=1918&sha=c726c3f3469a7fa57d214f6959cbbf286b4baeef&name_0=PR&name_1=Stress+test+%28amd_release%29). Same failure on PRs 1895, 1912, 1923 across amd_debug, amd_release, amd_tsan, amd_ubsan, amd_msan, arm_asan, arm_asan (s3) on 2026-06-22 → 2026-06-30.
Summary
When a Hybrid table is created in a non-default database using currentDatabase() inside remote() arguments, the function call is stored verbatim in the metadata file. On the next server start, the ATTACH TABLE statement is executed without any session database context, so currentDatabase() evaluates to default instead of the original database. The referenced table is not found and the server cannot start.
This is a recurring Stress test / Cannot start clickhouse-server failure across all antalya-26.3 stress flavors (amd_debug, amd_release, amd_tsan, amd_ubsan, amd_msan, arm_asan), seen continuously on every PR since 2026-06-22.
Error
Code: 60. DB::Exception: Table default.local_cold does not exist.
Maybe you meant test_3.local_cold?
Cannot attach table `test_3`.`t_settings_only` from metadata file
store/119/119a0976-0350-4f2d-aac5-d499b081fca5/t_settings_only.sql
from query:
ATTACH TABLE test_3.t_settings_only UUID '66e37911-f721-43e8-b657-6e352221f3ef'
(`ts` DateTime, `value` UInt64)
ENGINE = Hybrid(
remote('localhost:9000', 'test_3', 'local_hot'),
ts > hybridParam('hybrid_watermark_hot', 'DateTime'),
remote('localhost:9000', currentDatabase(), 'local_cold'),
ts <= hybridParam('hybrid_watermark_hot', 'DateTime')
)
SETTINGS hybrid_watermark_hot = '2025-09-01'
How to reproduce
-- Run in database test_3 (any non-default database)
CREATE DATABASE IF NOT EXISTS test_3;
CREATE TABLE test_3.local_hot (ts DateTime, value UInt64) ENGINE = MergeTree ORDER BY ts;
CREATE TABLE test_3.local_cold (ts DateTime, value UInt64) ENGINE = MergeTree ORDER BY ts;
CREATE TABLE test_3.t_settings_only (ts DateTime, value UInt64)
ENGINE = Hybrid(
remote('localhost:9000', 'test_3', 'local_hot'),
ts > hybridParam('hybrid_watermark_hot', 'DateTime'),
remote('localhost:9000', currentDatabase(), 'local_cold'),
ts <= hybridParam('hybrid_watermark_hot', 'DateTime')
)
SETTINGS hybrid_watermark_hot = '2025-09-01';
-- Restart the server. It will fail to start with Code: 60.
Root cause
At CREATE TABLE time, currentDatabase() returns test_3 correctly. However, the Hybrid engine stores the engine arguments as-is in the .sql metadata file without resolving the function call to its current value. The stored file therefore contains the literal token currentDatabase().
When the server restarts, it replays all ATTACH TABLE statements from metadata files. At that point there is no active session and no database context, so currentDatabase() returns default. The remote() call resolves to default.local_cold, which does not exist.
The Distributed engine had the identical bug and it was fixed in upstream ClickHouse PR #14211 (v20.10, 2020) by applying AddDefaultDatabaseVisitor to the engine AST before persisting metadata. This substitutes currentDatabase() with the resolved string literal at CREATE time. The Hybrid engine — introduced later and built on StorageDistributed — was never given the same treatment.
The pattern is also actively promoted in the hybridParam documentation and PR #1659 examples:
-- From PR #1659 docs — this pattern breaks on restart
ENGINE = Hybrid(
cluster('cluster1', currentDatabase(), 'hot'), ...
cluster('cluster2', currentDatabase(), 'cold'), ...
)
Fix
In src/Storages/StorageDistributed.cpp, inside registerStorageHybrid (the Hybrid-specific CREATE path), apply the same AddDefaultDatabaseVisitor pass that StorageDistributed::create uses for Distributed tables. This resolves currentDatabase() in all segment table-function arguments and writes the resolved name to disk.
// Pseudocode — mirrors the existing Distributed fix
AddDefaultDatabaseVisitor visitor(local_context, local_context->getCurrentDatabase());
visitor.visit(args); // replaces currentDatabase() with the actual db name in-place
// then proceed with metadata write
After this fix, the stored metadata for the table above would read:
remote('localhost:9000', 'test_3', 'local_cold')
instead of:
remote('localhost:9000', currentDatabase(), 'local_cold')
Impact
| Dimension |
Detail |
| Affected builds |
antalya-26.3 (all flavors) |
| First seen |
2026-06-22 |
| Scope |
Any Hybrid table created in a non-default database with currentDatabase() in segment arguments |
| Symptom |
Server cannot start after restart — UNKNOWN_TABLE on ATTACH |
| Workaround |
Use explicit database names in remote() / cluster() arguments instead of currentDatabase() |
| PR that introduced the pattern |
Altinity/ClickHouse #1659 — hybridParam / ALTER TABLE MODIFY SETTING for watermarks |
Workaround (until fix lands)
Replace currentDatabase() with the explicit database name in all Hybrid engine segment arguments:
-- Instead of:
remote('localhost:9000', currentDatabase(), 'local_cold')
-- Write:
remote('localhost:9000', 'my_database', 'local_cold')
Identified: 2026-07-01
Type of problem
Code bug —
currentDatabase()is not resolved atCREATE TABLEtime in the Hybrid engine, causing every server restart to fail withUNKNOWN_TABLEwhen the table was created in a non-default database.Because of it now stress test fails on every pr (exmaple https://altinity-build-artifacts.s3.amazonaws.com/json.html?PR=1918&sha=c726c3f3469a7fa57d214f6959cbbf286b4baeef&name_0=PR&name_1=Stress+test+%28amd_release%29). Same failure on PRs 1895, 1912, 1923 across amd_debug, amd_release, amd_tsan, amd_ubsan, amd_msan, arm_asan, arm_asan (s3) on 2026-06-22 → 2026-06-30.
Summary
When a
Hybridtable is created in a non-default database usingcurrentDatabase()insideremote()arguments, the function call is stored verbatim in the metadata file. On the next server start, theATTACH TABLEstatement is executed without any session database context, socurrentDatabase()evaluates todefaultinstead of the original database. The referenced table is not found and the server cannot start.This is a recurring
Stress test / Cannot start clickhouse-serverfailure across allantalya-26.3stress flavors (amd_debug,amd_release,amd_tsan,amd_ubsan,amd_msan,arm_asan), seen continuously on every PR since 2026-06-22.Error
How to reproduce
Root cause
At
CREATE TABLEtime,currentDatabase()returnstest_3correctly. However, the Hybrid engine stores the engine arguments as-is in the.sqlmetadata file without resolving the function call to its current value. The stored file therefore contains the literal tokencurrentDatabase().When the server restarts, it replays all
ATTACH TABLEstatements from metadata files. At that point there is no active session and no database context, socurrentDatabase()returnsdefault. Theremote()call resolves todefault.local_cold, which does not exist.The Distributed engine had the identical bug and it was fixed in upstream ClickHouse PR #14211 (v20.10, 2020) by applying
AddDefaultDatabaseVisitorto the engine AST before persisting metadata. This substitutescurrentDatabase()with the resolved string literal at CREATE time. The Hybrid engine — introduced later and built onStorageDistributed— was never given the same treatment.The pattern is also actively promoted in the
hybridParamdocumentation and PR #1659 examples:Fix
In
src/Storages/StorageDistributed.cpp, insideregisterStorageHybrid(the Hybrid-specific CREATE path), apply the sameAddDefaultDatabaseVisitorpass thatStorageDistributed::createuses for Distributed tables. This resolvescurrentDatabase()in all segment table-function arguments and writes the resolved name to disk.After this fix, the stored metadata for the table above would read:
instead of:
Impact
antalya-26.3(all flavors)Hybridtable created in a non-default database withcurrentDatabase()in segment argumentsUNKNOWN_TABLEonATTACHremote()/cluster()arguments instead ofcurrentDatabase()hybridParam/ ALTER TABLE MODIFY SETTING for watermarksWorkaround (until fix lands)
Replace
currentDatabase()with the explicit database name in all Hybrid engine segment arguments:Identified: 2026-07-01