HMCL-dev/HMCL · error · IOException

level.dat missing Data

Error message

level.dat missing Data

What it means

Thrown by loadAndCheckLevelData after parsing level.dat: the root NBT compound has no 'Data' child compound tag. Vanilla Minecraft always stores world metadata under Data, so its absence means the file is corrupt or not a real level.dat.

Solutions

  1. Restore level.dat from a backup of the world
  2. Re-copy the world from the source Minecraft installation
  3. Verify level.dat is gzip-compressed NBT with a root compound containing Data (inspect with an NBT editor)
  4. If the file is truncated (size 0 or far below ~800 bytes), regenerate the world or accept data loss
Defensive patterns

Strategy: try-catch

Validate before calling

// Decompress and sanity-check before constructing World:
// gzip -t level.dat succeeds and the file is at least a few hundred bytes
static boolean levelDatPlausible(Path dir) throws IOException {
    Path ld = dir.resolve("level.dat");
    return Files.isRegularFile(ld) && Files.size(ld) > 0;
}

Type guard

static boolean hasLevelData(Path worldDir) {
    return Files.isRegularFile(worldDir.resolve("level.dat"));
}

Try / catch

try {
    World world = new World(worldDir);
} catch (IOException e) {
    if (String.valueOf(e.getMessage()).equals("level.dat missing Data")) {
        // restore from backup or notify user the world metadata is corrupt
    }
}

Prevention

When it happens

Trigger: Calling new World(worldDir) or loadAndCheckWorldData on a level.dat whose decompressed NBT root lacks the Data compound tag.

Common situations: A level.dat corrupted by a crash or disk failure, a truncated download/copy, a zero-byte or placeholder level.dat created by a faulty backup tool, or hand-crafted NBT files used in tests.

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 HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/273ccc430aaaf55b. Report an issue: GitHub.

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java:247

    }

    public boolean supportQuickPlay() {
        return getGameVersion() != null && getGameVersion().isAtLeast("1.20", "23w14a");
    }

    public static boolean supportQuickPlay(GameVersionNumber gameVersionNumber) {
        return gameVersionNumber != null && gameVersionNumber.isAtLeast("1.20", "23w14a");
    }

    private void loadAndCheckWorldData() throws IOException {
        loadAndCheckLevelData(levelDataPath);
        loadOtherData();
    }

    private void loadAndCheckLevelData(Path levelDat) throws IOException {
        this.levelData = NBTCodec.of().readTag(levelDat, TagType.COMPOUND);
        if (!(levelData.get("Data") instanceof CompoundTag data))
            throw new IOException("level.dat missing Data");

        if (!(data.get("LevelName") instanceof StringTag))
            throw new IOException("level.dat missing LevelName");

        if (!(data.get("LastPlayed") instanceof LongTag))
            throw new IOException("level.dat missing LastPlayed");
        this.dataTag = data;
    }

    private void loadOtherData() throws IOException {
        if (!(levelData.get("Data") instanceof CompoundTag data)) return;

        Path worldGenSettingsDatPath = file.resolve("data/minecraft/world_gen_settings.dat");
        if (data.get("WorldGenSettings") instanceof CompoundTag worldGenSettingsTag) {
            setWorldGenSettingsData(null, worldGenSettingsTag, worldGenSettingsTag);
        } else if (Files.isRegularFile(worldGenSettingsDatPath)) {
            CompoundTag raw = NBTCodec.of().readTag(worldGenSettingsDatPath, TagType.COMPOUND);
            if (raw.get("data") instanceof CompoundTag compoundTag) {

View on GitHub (pinned to 24702dc5a0)