quickwit-oss/quickwit · error
sort schema does not contain timeseries_id — sorted_series…
Error message
sort schema does not contain timeseries_id — sorted_series key requires it as the guaranteed discriminator for series identity
What it means
resolve_key_columns walks the sort schema and requires timeseries_id to be present in it, since sorted_series keys need the series-identity hash as a tiebreaker. If the configured sort schema never lists a column named timeseries_id (the loop ends without setting ts_id_column), this error is raised.
Solutions
- Add a timeseries_id entry to the sort schema configuration before the first timestamp column.
- Validate the SortSchema at config-load time so bad schemas fail early rather than at merge time.
- If the schema comes from a template/older format, migrate it to include the timeseries_id discriminator.
Example fix
// before: sort_schema columns = [service, metric_name, timestamp] // after: sort_schema columns = [service, metric_name, timeseries_id, timestamp] // (timeseries_id must appear before any timestamp column)
Defensive patterns
Strategy: validation
Validate before calling
if !sort_schema.column.iter().any(|c| c.name == "timeseries_id") {
return Err(anyhow!("invalid sort schema: timeseries_id is required"));
}
Try / catch
match result {
Err(e) if e.to_string().contains("sort schema does not contain timeseries_id") => {
// fix config and reload: sort_schema.columns.insert(idx, timeseries_id_col)
return Err(e.context("fix the index sort-schema configuration"));
}
other => other,
}
Prevention
- Validate sort schemas at index-creation time to require timeseries_id before any timestamp column.
- Centralize sort-schema construction in one helper that always appends the timeseries_id entry.
- Add a config linter/test covering generated and user-supplied sort schemas.
When it happens
Trigger: compute_sorted_series_column invoked with a SortSchema proto whose column list omits timeseries_id — a misconfigured or truncated sort schema, or a schema built dynamically that stopped before adding the hash column.
Common situations: Hand-written index config with a custom sort schema missing timeseries_id; schema generated from user-supplied sort fields only; a proto built from older config formats that did not include it.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- input has sort_fields ' ', expected
- num_outputs must be at least 1
- num_outputs must be at least 1
- sort schema mismatch in
- timeseries_id column is required in the batch for…
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/33085c2ac47516a6.
Report an issue: GitHub.
Appendix: source
Thrown at quickwit/quickwit-parquet-engine/src/sorted_series/mod.rs:210
});
break;
}
if crate::sort_fields::is_timestamp_column_name(&col.name) {
break;
}
let is_descending = col.sort_direction
== quickwit_proto::sortschema::SortColumnDirection::SortDirectionDescending as i32;
if let Ok(idx) = batch_schema.index_of(&col.name) {
tag_columns.push(KeyColumn {
ordinal: ordinal as u8,
batch_idx: idx,
descending: is_descending,
});
}
}
let ts_id_column = ts_id_column.ok_or_else(|| {
anyhow!(
"sort schema does not contain timeseries_id — sorted_series key requires it as the \
guaranteed discriminator for series identity"
)
})?;
Ok(ResolvedKeySchema {
tag_columns,
ts_id_column,
})
}
/// Encode a single row's sorted series key into `buf`.
///
/// For ascending columns, storekey bytes are written directly — memcmp
/// gives ascending order. For descending columns, the storekey bytes for
/// that column's (ordinal, value) pair are bitwise-NOTed so that ascending
/// memcmp on the composite key gives the correct descending order.
/// This is the standard ordered-code technique (see Google's OrderedCode).View on GitHub (pinned to a39730c5cd)