influxdata/influxdb · error
column id in series key should be valid
Error message
column id in series key should be valid
What it means
A `.expect(...)` panic in the catalog's `create_last_cache` update path: when value/key columns are not explicitly given, the cache key columns are derived from the table's `series_key` column ids, and each id is looked up in `column_definition_by_id`. The assertion states every series-key column id must have a definition; a lookup miss means the table's series_key references a column that does not exist in its own definition map.
Solutions
- Pass explicit `key_columns` to `create_last_cache` so the series-key derivation path (and its fragile lookup) is skipped.
- Inspect the table's schema in the catalog and repair/remove the dangling series_key entry referencing the missing column id.
- Restore the affected table/catalog from a consistent backup.
- Replace the `expect` with a proper error (e.g. `KeyColumnDoesNotExistByName`) so create_last_cache fails gracefully on inconsistent schemas.
Example fix
// before
.expect("column id in series key should be valid")
// after
.ok_or_else(|| anyhow!("series key references missing column id {}", ColumnIdentifier::tag(*id)))? Defensive patterns
Strategy: validation
Validate before calling
// verify every series_key id resolves before calling create_last_cache without key_columns
for id in &table.series_key {
assert!(
table.column_definition_by_id(&ColumnIdentifier::tag(*id)).is_some(),
"series_key references missing column id {id}"
);
} Type guard
fn series_key_resolves(tbl: &TableSnapshot) -> bool {
tbl.series_key.iter().all(|id| tbl.column_definition_by_id(&ColumnIdentifier::tag(*id)).is_some())
} Try / catch
// panic path; pass explicit key columns when the schema is suspect
if !series_key_resolves(&tbl) {
create_last_cache(table, /* explicit key_columns */, value_columns)?;
} Prevention
- Pass explicit key_columns to create_last_cache instead of relying on series-key derivation.
- After dropping columns, verify series_key was updated to remove the dropped ids.
- Restore catalogs from consistent snapshots, never hand-merge table definitions.
- Audit table schemas (series_key vs column map) after upgrades or restores.
When it happens
Trigger: Calling `create_last_cache` without explicit key columns on a table whose `series_key` contains a column id missing from `column_definition_by_id` — i.e. catalog inconsistency (stale/dangling series_key after a column drop or partial schema update).
Common situations: Catalogs mutated by older/buggy versions that dropped columns without cleaning series_key; hand-restored or merged catalog snapshots; migrations that rebuilt column maps but not series keys.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- auto field family exists
- database should exist by id
- duration not to overflow
- Existing transaction for table should not exist
- field does not exist
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/e7acfc02b44ad60c.
Report an issue: GitHub.
Appendix: source
Thrown at influxdb3_catalog/src/catalog/versions/v2/update.rs:954
)
.as_str(),
)
})
.and_then(|def| {
if is_valid_last_cache_key_col(&def) {
Ok((def.id(), name.as_ref().to_string()))
} else {
Err(CatalogError::InvalidLastCacheKeyColumnType)
}
})
})
.collect::<Result<(Vec<ColumnIdentifier>, Vec<String>)>>()?
} else {
tbl.series_key
.iter()
.map(|id| {
tbl.column_definition_by_id(&ColumnIdentifier::tag(*id))
.expect("column id in series key should be valid")
})
.map(|def| Ok((def.id(), def.name().to_string())))
.collect::<Result<(Vec<ColumnIdentifier>, Vec<String>)>>()?
};
let value_columns = if let Some(value_columns) = value_columns {
let columns = value_columns
.iter()
.map(|name| {
tbl.column_definition(name.as_ref())
.map(|def| def.id())
.ok_or_else(|| {
CatalogError::invalid_configuration(
format!(
"invalid value column provided: {name}",
name = name.as_ref()
)
.as_str(),View on GitHub (pinned to 06200ef96b)