Summary
Every render of a metric builder chart that uses a groupBy (and the corresponding alerts) emits an extra ClickHouse statement:
DESCRIBE TABLE ``.Bucketed FORMAT JSON
which always fails with Code: 60. DB::Exception: Table default.Bucketed does not exist. (UNKNOWN_TABLE). The chart/alert itself works fine (the real query runs via the Bucketed CTE), so it's non-fatal — but it logs a ClickHouse <Error> on every evaluation and adds a wasted failing round-trip.
In our deployment a single 5-minute metric alert (a gauge grouped by pod) produced ~250+ ClickHouse error-log lines per 12h, which is noisy and misleading when scanning ClickHouse error logs.
Version: HyperDX 2.27.0 · ClickHouse 25.7.8.71
Reproduce
- Create a dashboard tile on a gauge metric with a
groupBy, e.g. metric k8s.pod.memory_limit_utilization grouped by ResourceAttributes['k8s.pod.name'].
- (Optionally create an alert on it so it evaluates on a fixed interval.)
- Watch the ClickHouse server logs — each evaluation logs
DESCRIBE TABLE \`.Bucketed ... (UNKNOWN_TABLE)`.
Root cause
For grouped metric rendering, renderChartConfig builds a synthetic Bucketed CTE and then re-points the chart config's from at it:
- Gauge path:
packages/common-utils/src/core/renderChartConfig.ts ~L1375 (CTE) / L1407-1410 (from: { databaseName: '', tableName: 'Bucketed' }).
- Sum/
increase group-limit path: ~L1502 (CTE) / L1577 (from: { databaseName: '', tableName: 'Bucketed' }).
The Bucketed CTE is intentional and necessary (its comments explain it wraps the aggregation so Rate/Sum/LastValue are exposed as plain columns — avoiding illegal sum(sum(...)) — and enables top-N group ranking). The problem is only that, while rendering against this synthetic from, a column-metadata lookup (Metadata.getColumns, which issues DESCRIBE ... — packages/common-utils/src/core/metadata.ts L275) runs against the CTE name. A CTE can't be DESCRIBEd as a standalone table, so ClickHouse returns UNKNOWN_TABLE.
Notably the codebase already guards for this in the time-filter path — skipColumnLookup at renderChartConfig.ts L738 skips the metadata lookup when hasSubqueryCte(withClauses) && !databaseName (FROM is a CTE alias with no real base table). The same CTE-aware skip just isn't applied to the column-metadata lookup that resolves the select/groupBy columns for the Bucketed-backed config — so that one still DESCRIBEs the CTE.
Suggested direction
Don't remove the Bucketed CTE (it's required). Instead extend the existing CTE-aware skip so a from whose databaseName is empty and whose tableName matches a declared with CTE is treated as "no base table to DESCRIBE" for all metadata column lookups, not just the time-filter one. (Or have getColumns short-circuit when the target is a known CTE.)
Related
Summary
Every render of a metric builder chart that uses a
groupBy(and the corresponding alerts) emits an extra ClickHouse statement:which always fails with
Code: 60. DB::Exception: Table default.Bucketed does not exist. (UNKNOWN_TABLE). The chart/alert itself works fine (the real query runs via theBucketedCTE), so it's non-fatal — but it logs a ClickHouse<Error>on every evaluation and adds a wasted failing round-trip.In our deployment a single 5-minute metric alert (a gauge grouped by pod) produced ~250+ ClickHouse error-log lines per 12h, which is noisy and misleading when scanning ClickHouse error logs.
Version: HyperDX 2.27.0 · ClickHouse 25.7.8.71
Reproduce
groupBy, e.g. metrick8s.pod.memory_limit_utilizationgrouped byResourceAttributes['k8s.pod.name'].DESCRIBE TABLE \`.Bucketed ... (UNKNOWN_TABLE)`.Root cause
For grouped metric rendering,
renderChartConfigbuilds a syntheticBucketedCTE and then re-points the chart config'sfromat it:packages/common-utils/src/core/renderChartConfig.ts~L1375 (CTE) / L1407-1410 (from: { databaseName: '', tableName: 'Bucketed' }).increasegroup-limit path: ~L1502 (CTE) / L1577 (from: { databaseName: '', tableName: 'Bucketed' }).The
BucketedCTE is intentional and necessary (its comments explain it wraps the aggregation soRate/Sum/LastValueare exposed as plain columns — avoiding illegalsum(sum(...))— and enables top-N group ranking). The problem is only that, while rendering against this syntheticfrom, a column-metadata lookup (Metadata.getColumns, which issuesDESCRIBE ...—packages/common-utils/src/core/metadata.tsL275) runs against the CTE name. A CTE can't beDESCRIBEd as a standalone table, so ClickHouse returnsUNKNOWN_TABLE.Notably the codebase already guards for this in the time-filter path —
skipColumnLookupatrenderChartConfig.tsL738 skips the metadata lookup whenhasSubqueryCte(withClauses) && !databaseName(FROM is a CTE alias with no real base table). The same CTE-aware skip just isn't applied to the column-metadata lookup that resolves the select/groupBy columns for theBucketed-backed config — so that one still DESCRIBEs the CTE.Suggested direction
Don't remove the
BucketedCTE (it's required). Instead extend the existing CTE-aware skip so afromwhosedatabaseNameis empty and whosetableNamematches a declaredwithCTE is treated as "no base table to DESCRIBE" for all metadata column lookups, not just the time-filter one. (Or havegetColumnsshort-circuit when the target is a known CTE.)Related