Anuken/Mindustry · error · IOException

Unknown save version: {}. Are you trying to load a save from

Error message

Unknown save version: {}. Are you trying to load a save from a newer version?

What it means

Raised by SaveIO.getMeta(DataInputStream) after reading the 4-byte version int and not finding it in the SaveIO.versions IntMap. The IOException is caught and rethrown as a RuntimeException, so callers see a RuntimeException whose cause is this message. The registered versions are Save1..Save13 (see SaveIO.java:23); any version int outside that set is rejected.

Source

Thrown at core/src/mindustry/io/SaveIO.java:100

    }

    public static SaveMeta getMeta(Fi file){
        try{
            return getMeta(getStream(file));
        }catch(Throwable e){
            Log.err(e);
            return getMeta(getBackupStream(file));
        }
    }

    public static SaveMeta getMeta(DataInputStream stream){

        try{
            readHeader(stream);
            int version = stream.readInt();
            SaveVersion ver = versions.get(version);

            if(ver == null) throw new IOException("Unknown save version: " + version + ". Are you trying to load a save from a newer version?");

            SaveMeta meta = ver.getMeta(stream);
            stream.close();
            return meta;
        }catch(IOException e){
            throw new RuntimeException(e);
        }
    }

    public static Fi fileFor(int slot){
        return saveDirectory.child(slot + "." + Vars.saveExtension);
    }

    public static Fi backupFileFor(Fi file){
        return file.sibling(file.name() + "-backup." + file.extension());
    }

    public static void write(Fi file, SaveOptions options){

View on GitHub (pinned to f695ad7e60)

Solutions

  1. Update the game to a build whose SaveIO.versionArray includes the version int printed in the message (match the build that wrote the save).
  2. If downgrading, re-save in an intermediate compatible version first.
  3. Catch RuntimeException around getMeta and present a 'save from a newer version' message to the user instead of crashing.
  4. For preview UIs, use isSaveValid to filter unreadable files before calling getMeta.

Example fix

// before
SaveMeta meta = SaveIO.getMeta(stream);

// after
SaveMeta meta;
try {
    meta = SaveIO.getMeta(stream);
} catch (RuntimeException e) {
    if (e.getCause() instanceof IOException) {
        throw new IllegalStateException("Save is from an incompatible game version", e);
    }
    throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Check version before reading meta in bulk
try (DataInputStream s = SaveIO.getStream(file)) {
    SaveIO.readHeader(s);
    int v = s.readInt();
    if (!SaveIO.versions.containsKey(v)) {
        // unsupported version; skip this file
    }
}

Type guard

null

Try / catch

try {
    SaveMeta meta = SaveIO.getMeta(stream);
} catch (RuntimeException e) {
    if (e.getCause() instanceof IOException ioe) {
        // version/header problem; report ioe.getMessage()
    }
}

Prevention

When it happens

Trigger: SaveIO.getMeta(stream) when the int after the MSAV header does not map to a registered SaveVersion; commonly invoked via getMeta(Fi) (preview/validity check) which then also tries the backup file.

Common situations: Save created by a newer or beta build whose version int is higher than Save13; save created by a much older build whose version was removed; a manually crafted or partially overwritten file where the version bytes are random.

Related errors


AI-assisted analysis of Anuken/Mindustry@f695ad7e60 (2026-08-14). Data as JSON: /api/errors/f623c374e5d3145f. Report an issue: GitHub.