influxdata/influxdb · error · ServiceLimitError

per-table column limits are restricted to a maximum value of

Error message

per-table column limits are restricted to a maximum value of {0} for system performance purposes

What it means

`ServiceLimitError::ColumnLimitTooLarge` is raised when the per-table column limit (`MaxColumnsPerTable`) is set above the hard maximum the system allows. The cap exists for system performance purposes: very wide tables degrade query and storage performance, so the library enforces an upper bound even though the value would otherwise fit in `i32`.

Solutions

  1. Lower the per-table column limit to the documented maximum shown in the error message.
  2. Restructure overly wide schemas (split data across multiple tables or use tags/fields appropriately) so fewer columns are needed.
  3. Check the `MAX_COLUMNS_PER_TABLE` constant/limit in the codebase to know the exact cap before configuring.
  4. Validate configured limits at startup so misconfigurations surface early.

Example fix

// before
ServiceLimitUpdate::MaxColumnsPerTable(MaxColumnsPerTable::new(10_000))
// after
ServiceLimitUpdate::MaxColumnsPerTable(MaxColumnsPerTable::new(200)) // within system cap
Defensive patterns

Strategy: validation

Validate before calling

fn validate_column_limit(limit: usize, max: usize) -> Result<(), String> {
    if limit > max { Err(format!("per-table column limits are restricted to a maximum value of {max}")) } else { Ok(()) }
}

Try / catch

match result {
    Err(ServiceLimitError::ColumnLimitTooLarge(max)) => {
        eprintln!("column limit too high; cap is {max:?}");
    }
    ...
}

Prevention

When it happens

Trigger: Converting/configuring a `MaxColumnsPerTable` service limit with a value larger than the compile-time maximum allowed by the system (the cap carried in the `MaxColumnsPerTable` argument of the variant).

Common situations: Deployments trying to ingest extremely wide schemas (hundreds/thousands of columns per table); misreading the limit as configurable without bound; copying limits from another InfluxDB IOx deployment with a higher cap.

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/4c651556ccafd45e. Report an issue: GitHub.

Appendix: source

Thrown at core/data_types/src/service_limits.rs:236

/// Errors converting from raw values to the service limits
#[derive(Error, Debug, Clone, Copy)]
pub enum ServiceLimitError {
    /// A negative or 0 value was specified; those aren't allowed
    #[error("service limit values must be greater than 0")]
    MustBeGreaterThanZero,

    /// No value was provided so we can't update anything
    #[error("a supported service limit value is required")]
    NoValueSpecified,

    /// Limits are stored as `i32` in the database and transferred as i32 over protobuf, so even
    /// though they are stored as `usize` in Rust, the `usize` value must be less than `i32::MAX`.
    #[error("service limit values must fit in a 32-bit signed integer (`i32`)")]
    MustFitInI32,

    /// Per-table column limits are restricted
    #[error(
        "per-table column limits are restricted to a maximum value of {0} for system performance purposes"
    )]
    ColumnLimitTooLarge(MaxColumnsPerTable),
}

impl ServiceLimitUpdate {
    /// Constructs a [`ServiceLimitUpdate`] from the provided `limit_update`,
    /// performing validation and applying `column_limit_upper_bound` to the
    /// per-table column limit.
    pub fn bounded_try_from(
        limit_update: Option<LimitUpdate>,
        column_limit_upper_bound: MaxColumnsPerTable,
    ) -> Result<Self, ServiceLimitError> {
        match limit_update {
            Some(LimitUpdate::MaxTables(n)) => Ok(Self::MaxTables(MaxTables::try_from(n)?)),
            Some(LimitUpdate::MaxColumnsPerTable(n)) => Ok(Self::MaxColumnsPerTable(
                MaxColumnsPerTable::try_from(n).map(|l| {
                    if l <= column_limit_upper_bound {

View on GitHub (pinned to 06200ef96b)