influxdata/influxdb · error · ProtoV1AnyWithStorageError

Error converting max_columns_per_table

Error message

Error converting max_columns_per_table: {0}

What it means

ProtoV1AnyWithStorageError::MaxColumnsPerTable is raised during conversion of a catalog-storage proto v1 NamespaceWithStorage/TableWithStorage when the max_columns_per_table field fails conversion into the ServiceLimit-bounded internal type — the stored value violates the column-count service limit.

Solutions

  1. Correct the proto's max_columns_per_table to a value within the ServiceLimit range
  2. Re-write the catalog storage object with valid limit values
  3. Verify version compatibility between the data writer and the converting library version

Example fix

// before (proto)
max_columns_per_table: 0 // invalid
// after
max_columns_per_table: 200 // valid service-limit value
Defensive patterns

Strategy: validation

Validate before calling

fn max_columns_valid(v: i64, limit: i64) -> bool {
    v > 0 && v <= limit
}

Try / catch

let ns = NamespaceWithStorage::try_from(proto).map_err(|e| match e {
    ProtoV1AnyWithStorageError::MaxColumnsPerTable(src) => anyhow!("bad max_columns_per_table: {}", src),
    other => anyhow!(other),
})?;

Prevention

When it happens

Trigger: Converting a v1 proto whose max_columns_per_table is outside the accepted ServiceLimit range or otherwise invalid for the internal type.

Common situations: Namespace settings from an older or external writer with unsupported column limits; corrupted or hand-modified protos; limit policy changes between releases invalidating stored values.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/ff8b1d4f4da99092. Report an issue: GitHub.

Appendix: source

Thrown at core/data_types/src/lib.rs:476

            max_columns_per_table: value.max_columns_per_table.get_i32(),
            partition_template: value.partition_template.as_proto().cloned(),
            size_bytes: value.size_bytes,
            table_count: value.table_count as i32,
            deleted_at: value.deleted_at.map(google::Timestamp::from),
        }
    }
}

/// Errors converting from a catalog_storage proto v1 NamespaceWithStorage or TableWithStorage to
/// [`NamespaceWithStorage`] or [`TableWithStorage`].
#[derive(Debug, Error)]
pub enum ProtoV1AnyWithStorageError {
    /// invalid value for MaxTables
    #[error("Error converting max_tables: {0}")]
    MaxTables(ServiceLimitError),

    /// invalid value for MaxColumnsPerTable
    #[error("Error converting max_columns_per_table: {0}")]
    MaxColumnsPerTable(ServiceLimitError),

    /// invalid value for PartitionTemplate
    #[error("Error converting partition_template: {0}")]
    PartitionTemplate(ValidationError),
}

impl TryFrom<catalog_storage_proto::NamespaceWithStorage> for NamespaceWithStorage {
    type Error = ProtoV1AnyWithStorageError;

    /// We require fallible conversion because generated protobuf structs can carry any i32
    /// value for `max_tables` and `max_columns_per_table`, which is larger than the domain
    /// `MaxTables` and `MaxColumnsPerTable` can represent (i.e. 0..=i32::MAX).
    /// The `partition_template` can also be invalid.
    fn try_from(value: catalog_storage_proto::NamespaceWithStorage) -> Result<Self, Self::Error> {
        let max_tables =
            MaxTables::try_from(value.max_tables).map_err(ProtoV1AnyWithStorageError::MaxTables)?;
        let max_columns_per_table = MaxColumnsPerTable::try_from(value.max_columns_per_table)

View on GitHub (pinned to 06200ef96b)