EpicGames/lore · error · io::Error (InvalidData)

level header file has unsupported version

Error message

level header file has unsupported version {}, expected {}

What it means

After the magic check, `read_level_header_file` validates `header.version` against `MARKER_VERSION`. A mismatch means the marker file was written by a different (older or newer) lore-storage on-disk format that this build cannot read. It fails with `ErrorKind::InvalidData` reporting both versions.

Solutions

  1. Upgrade lore-storage to the version that wrote `MARKER_VERSION` (the 'expected' value in the message shows what this build needs).
  2. Run any provided migration tooling to convert old-format stores.
  3. Re-seed/rebuild the store if no migration path exists.

Example fix

// before
let header = read_level_marker(dir).await?; // fails: unsupported version 2

// after
// pin the crate version that wrote the store, or migrate first:
// Cargo.toml: lore-storage = "= <version matching MARKER_VERSION>"
let header = read_level_marker(dir).await?;
Defensive patterns

Strategy: try-catch

Validate before calling

let bytes = tokio::fs::read(&header_path).await?;
let version = u32::from_le_bytes(bytes[4..8].try_into()?);
if version != MARKER_VERSION { /* migrate or use matching crate version */ }

Try / catch

match read_level_marker(dir).await {
    Err(e) if e.kind() == io::ErrorKind::InvalidData => {
        eprintln!("store written by a different lore-storage version; migrate first");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Opening a store whose level marker files were written by a different lore-storage version — typically upgrading or downgrading the library, or mixing store directories between versions.

Common situations: Rolling back a dependency version, copying a store directory between machines running different builds, or a beta/nightly format change without a migration path.

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 EpicGames/lore@074eb0b0d1 (2026-09-13). Data as JSON: /api/errors/b904e4766955d0f9. Report an issue: GitHub.

Appendix: source

Thrown at lore-storage/src/local/fan_out.rs:408

            std::io::ErrorKind::UnexpectedEof,
            format!(
                "level header file is {} bytes, expected {expected}",
                bytes.len()
            ),
        ));
    }
    header.as_mut_bytes().copy_from_slice(&bytes[..expected]);
    if header.magic != MARKER_MAGIC {
        return Err(std::io::Error::new(
            std::io::ErrorKind::InvalidData,
            format!(
                "level header file has invalid magic 0x{:08x}, expected 0x{:08x}",
                header.magic, MARKER_MAGIC
            ),
        ));
    }
    if header.version != MARKER_VERSION {
        return Err(std::io::Error::new(
            std::io::ErrorKind::InvalidData,
            format!(
                "level header file has unsupported version {}, expected {}",
                header.version, MARKER_VERSION
            ),
        ));
    }
    Ok(Some(header.bucket_count as usize))
}

/// The serialized level header as the one segment a gather writes.
///
/// Fixed size — the header's length is a compile-time constant — and behind a pointer, because
/// [`lore_io::StableBufList`] requires a segment to keep its address when the value moves and the
/// ring backend moves the segment list into its operation entry after taking the pointers.
struct LevelHeaderSegment(Box<[u8; size_of::<LevelMarkerHeader>()]>);

impl lore_io::StableBufList for LevelHeaderSegment {

View on GitHub (pinned to 074eb0b0d1)