influxdata/influxdb · info · CatalogError

no catalog changes to apply

Error message

no catalog changes to apply: {details}

What it means

CatalogError::NoCatalogChange { details } is returned when a requested mutation is idempotent: applying it would not change any catalog state. It is informational in nature — the current state already matches the requested state. details explains what was already in place.

Solutions

  1. Treat this variant as success in idempotent apply flows
  2. Skip the operation if the resource already matches the desired definition
  3. Compare requested vs existing schema/config before calling the API
  4. Match on CatalogError::NoCatalogChange and log at info level

Example fix

// before
let t = db.create_table(schema).await?;
// after
let t = match db.create_table(schema).await {
    Ok(t) => t,
    Err(CatalogError::NoCatalogChange { .. }) => db.table(schema.name()).unwrap(),
    Err(e) => return Err(e.into()),
};
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: diff desired vs current before applying
if db.table_schema(name)? == desired_schema {
    eprintln!("schema already matches; skipping create");
}

Type guard

fn is_no_change(err: &CatalogError) -> bool {
    matches!(err, CatalogError::NoCatalogChange { .. })
}

Try / catch

match db.create_table(schema).await {
    Ok(t) => t,
    Err(CatalogError::NoCatalogChange { details }) => {
        tracing::info!("idempotent apply: {details}");
        db.table(schema.name()).unwrap()
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Creating a table with a schema identical to the existing one; re-adding a column that already exists with the same type; re-running an idempotent DDL migration; setting a cache/trigger configuration identical to the current one.

Common situations: Deployment scripts or IaC re-applying desired-state DDL on every deploy; retry of a create that actually succeeded earlier; running migrations multiple times.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at influxdb3_catalog/src/error.rs:60

    Enterprise(#[from] EnterpriseCatalogError),

    #[error("object store error: {0:?}")]
    ObjectStore(#[from] ObjectStoreCatalogError),

    #[error("catalog format error: {0}")]
    Format(#[from] FormatError),

    #[error("attempted to create a resource that already exists")]
    AlreadyExists,

    #[error("the requested resource was not found: {0}")]
    NotFound(String),

    #[error("attempted to modify resource that was already deleted: {0}")]
    AlreadyDeleted(String),

    /// Request is idempotent: no catalog state would change.
    #[error("no catalog changes to apply: {details}")]
    NoCatalogChange { details: String },

    /// Request is invalid.
    #[error("catalog internal error: {details}")]
    Internal { details: String },

    #[error(
        "persisted catalog checkpoint sequence {checkpoint_sequence} is ahead of live catalog sequence {live_sequence}"
    )]
    BackupCheckpointAhead {
        checkpoint_sequence: u64,
        live_sequence: u64,
    },

    #[error("invalid configuration provided: {message}")]
    InvalidConfiguration { message: Box<str> },

    #[error("only tag and string columns are supported in the distinct cache")]

View on GitHub (pinned to 06200ef96b)