databendlabs/databend · error
Internal, AggregateBucketScatter only recv Partitioned…
Error message
Internal, AggregateBucketScatter only recv Partitioned AggregateMeta
What it means
AggregateBucketScatter::scatter partitions an input block's AggregateMeta into per-bucket chunks for distributed two-phase aggregation. It only accepts blocks whose meta is AggregateMeta::Partitioned; any other meta variant hits this unreachable!(), meaning an upstream pipeline stage produced metadata the scatter stage was never designed to handle. This is an internal pipeline invariant, not a user-facing error.
Solutions
- Check cluster node versions match (rolling upgrade completed) and rerun the query
- Verify the upstream partial-aggregate/transform produces AggregateMeta::Partitioned before the bucketed exchange
- If you wired a custom pipeline, only feed blocks whose meta was created via AggregateMeta::Partitioned
- If reproducible on a single version, capture the query plan and file a bug with the query profile
Defensive patterns
Strategy: try-catch
Validate before calling
// Before feeding the scatter: verify meta kind
fn is_partitioned_aggregate_meta(block: &DataBlock) -> bool {
block.get_meta()
.and_then(|m| AggregateMeta::downcast_ref_from(m))
.map(|m| matches!(m, AggregateMeta::Partitioned { .. }))
.unwrap_or(false)
} Type guard
fn ensure_partitioned(m: Option<&Arc<DataBlockMeta>>) -> Option<&AggregateMeta> {
m.and_then(AggregateMeta::downcast_ref_from)
.filter(|m| matches!(m, AggregateMeta::Partitioned { .. }))
} Try / catch
match res {
Err(e) if e.message().contains("AggregateBucketScatter only recv Partitioned") => {
// log query profile, check cluster version skew, retry on homogeneous nodes
}
Err(e) => return Err(e),
Ok(v) => v,
} Prevention
- Keep all cluster nodes on the same Databend version before running distributed aggregations
- Don't wire arbitrary blocks into a bucketed exchange scatter; only Partitioned AggregateMeta blocks
- After upgrading, rerun query regression tests on aggregation exchanges
- When reproducing, capture the query plan/profile for the bug report
When it happens
Trigger: execute() is called with a DataBlock whose meta is not AggregateMeta::Partitioned — e.g. a plain ungrouped AggregateMeta, a wrong meta type, or a block with no meta — typically after a planner change, an older/newer cluster node serializing incompatible packets, or a custom pipeline wiring a non-partitioned block into a bucketed exchange.
Common situations: Mixed-version Databend clusters during rolling upgrade where query fragments disagree on meta format; custom source/pipeline code feeding the bucket scatter directly; bugs in the partial-aggregation transform that emit non-partitioned AggregateMeta.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- unreachable!()
- _ => unreachable!()
- unexpected aggregate meta
- [TRANSFORM-AGGREGATOR] Invalid hash table state during…
- [TRANSFORM-AGGREGATOR] Invalid hash table state before spill
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/bf3ee8165c243360.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/service/src/pipelines/processors/transforms/aggregator/serde/aggregate_scatter.rs:426
.push(PartitionItem::BucketSpilled(payload));
}
}
}
chunks
.into_iter()
.map(|data| {
AggregateMeta::Partitioned {
bucket: None,
data: PartitionedData::Mixed(data),
}
.into_datablock()
})
.collect()
}
},
_ => {
unreachable!("Internal, AggregateBucketScatter only recv Partitioned AggregateMeta")
}
})
}
}
impl FlightScatter for AggregateBucketScatter {
fn name(&self) -> &'static str {
"Bucket"
}
fn execute(&self, data_block: DataBlock) -> Result<Vec<DataBlock>> {
self.scatter(data_block, false)
}
}
impl LocalScatter for AggregateBucketScatter {
fn name(&self) -> &'static str {
"Bucket"View on GitHub (pinned to 288d84d76e)