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

  1. Add a timeseries_id entry to the sort schema configuration before the first timestamp column.
  2. Validate the SortSchema at config-load time so bad schemas fail early rather than at merge time.
  3. 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

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


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)