influxdata/influxdb · critical · ApplyError

{0}

Error message

{0}

What it means

`ApplyError` is raised when a persisted WAL/log record cannot be applied to the in-memory catalog because the record is inconsistent with current state — indicating data corruption or a bug in the write path. The wrapped string names the record type and the specific mismatch so operators get actionable context. It is produced in `influxdb3_catalog/src/format/apply.rs` when replaying catalog format records.

Solutions

  1. Restore the catalog from a known-good backup/snapshot
  2. Inspect the catalog files for corruption or manual modification and repair or regenerate them
  3. Check for version mismatch between the catalog writer and the current influxdb3 build and upgrade/downgrade accordingly
  4. If reproducible, capture the record and file a bug — this usually indicates a write-path bug
Defensive patterns

Strategy: try-catch

Try / catch

match result {
    Err(ApplyError(msg)) => {
        log::error!("catalog corruption during apply: {msg}");
        // halt replay and restore from backup
    }
    r => r?,
}

Prevention

When it happens

Trigger: Opening or replaying the catalog log and encountering a record whose target entity is missing, already exists, or otherwise conflicts with current catalog state (`impl From<RepositoryError<I>> for ApplyError` also converts repository errors).

Common situations: Catalog file corruption after a crash or disk failure; manually editing or partially truncating catalog files; restoring an old snapshot over a newer catalog; version mismatch between writer and reader of the catalog format.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at influxdb3_catalog/src/format/apply.rs:62

use crate::format::records::RestoreCatalog;
use crate::object_store::versions::v3::ObjectStoreCatalog;
use crate::repository::RepositoryError;

use super::reader::LEGACY_GROUP_INDEX_ENTRY_SIZE;
use super::{
    CatalogFile, Decode, FormatError, Header, REGISTRY, Record, file_flags, record_ids,
    validate_record_flags,
};

/// Error returned when applying a catalog record fails.
///
/// An `ApplyError` indicates the persisted record is inconsistent with the
/// current in-memory catalog — typically data corruption or a bug in the
/// write path. The carried string identifies the record type and the
/// specific mismatch, intended to give operators actionable context in the
/// event of catalog corruption.
#[derive(Debug, Clone, Error)]
#[error("{0}")]
pub struct ApplyError(pub String);

impl<I: CatalogId> From<RepositoryError<I>> for ApplyError {
    fn from(e: RepositoryError<I>) -> Self {
        Self(e.to_string())
    }
}

/// Build a complete catalog file from a pre-encoded payload, header
/// counts, and flags. Shared by [`serialize_log_file`] and
/// [`serialize_snapshot_file`], which differ only in the header flags.
fn make_file_bytes(
    catalog_uuid: Uuid,
    sequence_number: u64,
    payload: Vec<u8>,
    record_count: u32,
    group_count: u32,
    flags: u16,

View on GitHub (pinned to 06200ef96b)