FuelLabs/fuel-core · error

Fragments use different compressions.

Error message

Fragments use different compressions.

What it means

Snapshot fragments merge only when their parquet compression settings match: merging a Parquet fragment compressed with one ZstdCompressionLevel into another with a different level fails with 'Fragments use different compressions.' (crates/chain-config/src/config/state/writer.rs:187). The compression level is part of the fragment identity because table data is concatenated verbatim. Note the tables vec is extended before the check runs, so a failed merge must be treated as poisoned — the merged value only exists on success.

Solutions

  1. Produce every fragment with the same ZstdCompressionLevel before merging.
  2. Centralize the compression level in one config value shared by all writers/workers.
  3. If levels already differ, re-encode the divergent fragment at the target level instead of merging mixed data.

Example fix

// before
let merged = fragment_a.merge(fragment_b)?; // level 3 vs level 22 → error

// after — one shared level for every fragment
let level = ZstdCompressionLevel::try_from(3u8)?; // same value everywhere
let a = FragmentData::Parquet { tables: a_tables, compression: level };
let b = FragmentData::Parquet { tables: b_tables, compression: level };
Defensive patterns

Strategy: validation

Validate before calling

// Configure every fragment writer from one shared level so merges always agree
let level = ZstdCompressionLevel::try_from(3u8)?; // single source of truth
// pass `level` to every writer/worker that produces fragments

Type guard

if let (
    FragmentData::Parquet { compression: a, .. },
    FragmentData::Parquet { compression: b, .. },
) = (&fragment_a.data, &fragment_b.data)
{
    anyhow::ensure!(a == b, "refusing to merge compressions {a:?} and {b:?}");
}

Try / catch

match fragment_a.merge(fragment_b) {
    Err(e) if e.to_string().contains("different compressions") => {
        // re-encode one fragment at the other's level, then merge again
        reencode_fragment(&fragment_b, target_level)?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling merge between two fragments produced with different ZstdCompressionLevel values — e.g. parallel snapshot workers each configured with their own level.

Common situations: Distributed snapshot generation where worker configs drift; changing compression config between runs and merging fragments from old and new runs.

Related errors


AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16). Data as JSON: /api/errors/48bf0f942c1780d6. Report an issue: GitHub.

Appendix: source

Thrown at crates/chain-config/src/config/state/writer.rs:187

                    builder: other_builder,
                    ..
                },
            ) => {
                builder.merge(other_builder);
            }
            #[cfg(feature = "parquet")]
            (
                FragmentData::Parquet {
                    tables,
                    compression,
                },
                FragmentData::Parquet {
                    tables: their_tables,
                    compression: their_compression,
                },
            ) => {
                tables.extend(their_tables);
                anyhow::ensure!(
                    *compression == their_compression,
                    "Fragments use different compressions."
                )
            }
            #[cfg(feature = "parquet")]
            (a, b) => anyhow::bail!(
                "Fragments don't have the same encoding and cannot be merged. Fragments: {a:?} and {b:?}"
            ),
        };

        Ok(self)
    }
}

#[derive(Debug, Clone)]
pub struct SnapshotFragment {
    dir: PathBuf,
    data: FragmentData,

View on GitHub (pinned to b9d4d170da)