Pumpkin-MC/Pumpkin · critical · WorldInfoError

Unsupported world level version

Error message

Unsupported world level version: {0}

What it means

WorldInfoError::UnsupportedLevelVersion(i32) is returned when level.dat's 'version' (level format version) integer lies outside MINIMUM_SUPPORTED_LEVEL_VERSION..=MAXIMUM_SUPPORTED_LEVEL_VERSION, as checked by check_level_version (anvil.rs:59-75). Unlike DataVersion, this gates the on-disk level format version rather than the content data version.

Solutions

  1. Inspect level.dat's 'version' tag with an NBT viewer and compare against the server's supported level version range.
  2. Migrate the world by loading and re-saving it in a vanilla client version whose level version is supported.
  3. Restore level.dat from backup if the 'version' tag was accidentally edited or corrupted.
  4. Update the server build if the world uses a newer level format than the current binary supports.

Example fix

// before: loading a legacy world directly
let level = reader.read_world_info(&path)?; // UnsupportedLevelVersion(19133)
// after: reject unsupported level versions with a clear message
if !SUPPORTED_LEVEL_VERSIONS.contains(&lv) {
    bail!("migrate world first; level version {lv} unsupported");
}
let level = reader.read_world_info(&path)?;
Defensive patterns

Strategy: validation

Validate before calling

fn level_version_supported(path: &Path) -> Result<bool, String> {
    let root = read_level_dat_root(path).map_err(|e| e.to_string())?;
    let lv = root.get_compound("Data")
        .and_then(|d| d.get_int("version"))
        .ok_or("no version tag")?;
    Ok((MINIMUM_SUPPORTED_LEVEL_VERSION..=MAXIMUM_SUPPORTED_LEVEL_VERSION).contains(&lv))
}

Type guard

fn supported_level_version(lv: i32) -> bool {
    (MINIMUM_SUPPORTED_LEVEL_VERSION..=MAXIMUM_SUPPORTED_LEVEL_VERSION).contains(&lv)
}

Try / catch

match reader.read_world_info(&path) {
    Err(WorldInfoError::UnsupportedLevelVersion(lv)) => {
        bail!("level format version {lv} unsupported — re-save the world in a supported vanilla version");
    }
    other => { other?; }
}

Prevention

When it happens

Trigger: WorldInfoReader::read_world_info reads a level.dat whose 'Data'.'version' int is missing the supported range — e.g. a level format produced by a different Minecraft generation or a modified level.dat.

Common situations: Worlds converted between level formats by third-party tools; very old legacy worlds; hand-edited level.dat with a wrong 'version' tag; worlds from Minecraft versions the server doesn't support.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09). Data as JSON: /api/errors/f9252624cfd38460. Report an issue: GitHub.

Appendix: source

Thrown at crates/pumpkin-world/src/world_info/mod.rs:377

}

#[derive(Error, Debug)]
pub enum WorldInfoError {
    #[error("Io error: {0}")]
    IoError(std::io::ErrorKind),
    #[error("Info not found!")]
    InfoNotFound,
    #[error("Deserialization error: {0}")]
    DeserializationError(String),
    #[error(
        "No world seed found: neither level.dat nor data/minecraft/world_gen_settings.dat contains one"
    )]
    MissingWorldSeed,
    #[error("Serialization error: {0}")]
    SerializationError(String),
    #[error("Unsupported world data version: {0}")]
    UnsupportedDataVersion(i32),
    #[error("Unsupported world level version: {0}")]
    UnsupportedLevelVersion(i32),
}

impl From<std::io::Error> for WorldInfoError {
    fn from(value: std::io::Error) -> Self {
        match value.kind() {
            std::io::ErrorKind::NotFound => Self::InfoNotFound,
            value => Self::IoError(value),
        }
    }
}

View on GitHub (pinned to 8d4639e25a)