quickwit-oss/quickwit · error
input {} has index_uid '{}', expected '{}'
Error message
input {} has index_uid '{}', expected '{}' What it means
merge_parquet_split_metadata enforces that all input splits belong to the same index. This bail fires when input i's `index_uid` differs from `inputs[0].index_uid`. A merge can only produce output metadata for one index, so cross-index inputs indicate a broken compaction-scope selection.
Source
Thrown at quickwit/quickwit-parquet-engine/src/merge/metadata_aggregation.rs:73
) -> Result<ParquetSplitMetadata> {
if inputs.is_empty() {
bail!("merge_parquet_split_metadata requires at least one input split");
}
let first = &inputs[0];
// Validate invariant fields: all inputs must agree on these.
for (i, input) in inputs.iter().enumerate().skip(1) {
if input.kind != first.kind {
bail!(
"input {} has kind {:?}, expected {:?}",
i,
input.kind,
first.kind
);
}
if input.index_uid != first.index_uid {
bail!(
"input {} has index_uid '{}', expected '{}'",
i,
input.index_uid,
first.index_uid
);
}
if input.partition_id != first.partition_id {
bail!(
"input {} has partition_id {}, expected {}",
i,
input.partition_id,
first.partition_id
);
}
if input.sort_fields != first.sort_fields {
bail!(
"input {} has sort_fields '{}', expected '{}'",
i,View on GitHub (pinned to a39730c5cd)
Solutions
- Fix the merge task grouping to include index_uid in the scope key so only same-index splits are merged together.
- Check for stale splits from a deleted/recreated index and purge them from the merge candidate set.
- Verify the split metadata source (task queue / metastore fetch) filters by the current index_uid.
- In tests, use a constructor helper that stamps one shared index_uid on every input.
Example fix
// before candidates.retain(|s| s.partition_id == task.partition_id); // after candidates.retain(|s| s.index_uid == task.index_uid && s.partition_id == task.partition_id);
Defensive patterns
Strategy: validation
Validate before calling
fn single_index(inputs: &[ParquetSplitMetadata]) -> bool {
inputs.iter().all(|s| s.index_uid == inputs[0].index_uid)
} Type guard
fn same_index_uid(inputs: &[ParquetSplitMetadata]) -> Option<&str> {
let uid = &inputs.first()?.index_uid;
inputs.iter().all(|s| &s.index_uid == uid).then_some(uid.as_str())
} Try / catch
match merge_parquet_split_metadata(&inputs, &output, mixed) {
Err(e) if e.to_string().contains("index_uid") => {
error!("cross-index merge task detected: {e:#}; dropping task and alerting");
// quarantine the task, do not retry as-is
}
other => other?,
} Prevention
- Always filter merge candidates by index_uid at the metastore query level.
- Purge stale splits when an index is deleted and recreated.
- Include index_uid in task IDs / queue routing so cross-index batches can't form.
When it happens
Trigger: Calling merge_parquet_split_metadata with inputs whose ParquetSplitMetadata.index_uid values differ — e.g. the merge planner grouped tasks by partition_id but not index_uid, or split metadata was deserialized from the wrong index task queue.
Common situations: Control-plane bug assigning splits from two indexes to one indexing task; index deletion/re-creation reusing a partition id while stale splits from the old index remain; test fixtures with copy-pasted index_uids.
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
- input {} has kind {:?}, expected {:?}
- input {} has partition_id {}, expected {}
- input {} has sort_fields '{}', expected '{}'
- input {} has window {:?}, expected {:?}
- input {} has rg_partition_prefix_len {}, expected {} — split
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/9ed014197a8fa066.
Report an issue: GitHub.