influxdata/influxdb · error

invalid IOx metadata

Error message

invalid IOx metadata

What it means

TableMetaData::to_parquet_file converts an IoxParquetMetaData (thrift-encoded, zstd-compressed parquet footer bytes kept separate from the data) into catalog ParquetFileParams, and starts by calling metadata.decode().expect("invalid IOx metadata"). decode() is fallible; it fails when the stored metadata bytes are not valid IOx parquet metadata — corrupted objects, foreign parquet files, or bytes written by an incompatible IOx version.

Source

Thrown at core/parquet_file/src/metadata.rs:452

            compaction_level: CompactionLevel::Initial,
            sort_key: None,
            max_l0_created_at: MaxL0CreatedAt::NotCompacted,
        }
    }

    /// Create a corresponding iox catalog's ParquetFile
    pub fn to_parquet_file<F>(
        &self,
        partition_id: PartitionId,
        partition_hash_id: PartitionHashId,
        file_size_bytes: u64,
        metadata: &IoxParquetMetaData,
        column_id_map: F,
    ) -> ParquetFileParams
    where
        F: for<'a> Fn(&'a str) -> ColumnId,
    {
        let decoded = metadata.decode().expect("invalid IOx metadata");
        trace!(
            ?partition_id,
            ?decoded,
            "DecodedIoxParquetMetaData decoded from its IoxParquetMetaData"
        );
        let row_count = decoded.row_count();
        if decoded.md.row_groups().is_empty() {
            debug!(
                ?partition_id,
                "Decoded IoxParquetMetaData has no row groups to provide useful statistics"
            );
        }

        // Derive the min/max timestamp from the Parquet column statistics.
        let schema = decoded
            .read_schema()
            .expect("failed to read encoded schema");
        let stats = decoded

View on GitHub (pinned to d28e26e048)

Solutions

  1. Pre-validate before to_parquet_file: call metadata.decode() yourself (it returns Result) and handle the Err instead of letting the expect panic.
  2. Verify the object's integrity (size, checksum/ETag) against the catalog record to catch corruption/truncation.
  3. Confirm the file was written by the IOx write path with the same version; re-write or re-ingest foreign parquet files through IOx.
  4. File/track the upstream conversion expecting to take Result and propagate the error properly.

Example fix

// before
let params = table_meta.to_parquet_file(pid, phid, size, &iox_meta, &col_map); // panics via expect

// after
match iox_meta.decode() {
    Ok(_) => table_meta.to_parquet_file(pid, phid, size, &iox_meta, &col_map),
    Err(e) => {
        tracing::error!(%e, "object has invalid IOx metadata; skipping");
        return Err(e.into());
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// pre-validate the metadata bytes before the panicking conversion
use parquet_file::metadata::IoxParquetMetaData;

fn metadata_decodes(m: &IoxParquetMetaData) -> bool {
    m.decode().is_ok()
}

if !metadata_decodes(&iox_meta) {
    return quarantine(object_store_id, "undecodable IOx metadata");
}
let params = table_meta.to_parquet_file(pid, phid, size, &iox_meta, col_map);

Try / catch

// if you must call it on untrusted data, contain the panic and classify it
let params = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
    table_meta.to_parquet_file(pid, phid, size, &iox_meta, &col_map)
}));
let params = match params {
    Ok(p) => p,
    Err(payload) => {
        debug_assert_payload_mentions(&payload, "invalid IOx metadata");
        return Err(CatalogError::InvalidParquetMetadata.into());
    }
};

Prevention

When it happens

Trigger: Calling to_parquet_file on an IoxParquetMetaData whose bytes fail decoding: truncated/corrupted object-store payloads, parquet files produced by non-IOx writers (pandas/arrow/spark lack the IOx footer), or deserialization format changes between writer and reader versions.

Common situations: Catalog/compaction code loading files whose metadata blob was bit-rotted or partially written; ingesting externally-written parquet; upgrading IOx across a metadata encoding change; test fixtures with hand-built metadata bytes.

Related errors


AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16). Data as JSON: /api/errors/8bf33d932c7fccce. Report an issue: GitHub.