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
- Update the game to a build whose SaveIO.versionArray includes the version int printed in the message (match the build that wrote the save).
- If downgrading, re-save in an intermediate compatible version first.
- Catch RuntimeException around getMeta and present a 'save from a newer version' message to the user instead of crashing.
- 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
- Use isSaveValid to filter saves in selection UIs before getMeta.
- Match game build to the save's build before loading.
- Surface the version int from the message to the user for triage.
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
- Invalid asset type ID: {}. You are likely loading trying to
- Could not skip bytes. Expected length: {}; Actual length: {}
- Failed to read tile entity of block: {}
- Unknown object type:
- Unknown UI entry type:
AI-assisted analysis of Anuken/Mindustry@f695ad7e60 (2026-08-14).
Data as JSON: /api/errors/f623c374e5d3145f.
Report an issue: GitHub.