Anuken/Mindustry · error · IOException

Failed to read tile entity of block: {}

Error message

Failed to read tile entity of block: {}

What it means

In SaveVersion.readMap, when a center tile block has a building, the per-tile entity region is read via readChunkReads then tile.build.readAll(in, revision). Any Throwable thrown during that read is caught and rethrown as an IOException with the block name attached, which then surfaces through readRegion as an 'Error reading region map' wrapper. The original cause is preserved as the exception cause.

Source

Thrown at core/src/mindustry/io/SaveVersion.java:369

                //must be assigned after setBlock, because that can reset data
                if(hadData){
                    tile.data = data;
                    tile.floorData = floorData;
                    tile.overlayData = overlayData;
                    tile.extraData = extraData;
                    context.onReadTileData();
                }

                if(hadEntity){
                    if(isCenter){ //only read entity for center blocks
                        if(block.hasBuilding()){
                            try{
                                readChunkReads(stream, (in, len) -> {
                                    byte revision = in.b();
                                    tile.build.readAll(in, revision);
                                });
                            }catch(Throwable e){
                                throw new IOException("Failed to read tile entity of block: " + block, e);
                            }
                        }else{
                            //skip the entity region, as the entity and its IO code are now gone
                            skipChunk(stream);
                        }

                        context.onReadBuilding();
                    }
                }else if(!hadData){ //never read consecutive blocks if there's data
                    int consecutives = stream.readUnsignedByte();

                    for(int j = i + 1; j < i + 1 + consecutives; j++){
                        context.tile(j).setBlock(block);
                    }

                    i += consecutives;
                }
            }

View on GitHub (pinned to f695ad7e60)

Solutions

  1. Inspect the wrapped cause (getCause) and the block name in the message: a NoSuchField/ClassCastException indicates a version drift, an EOFException indicates truncation.
  2. Re-save the world in a build whose block IO matches, then load.
  3. Ensure the same mods (and versions) that created the save are enabled when loading.
  4. If you author a custom block, implement readAll defensively across revisions and bump the revision byte only when adding fields.
  5. Use the -backup file via SaveIO.load(Fi) which already retries once.

Example fix

// before
SaveIO.load(file); // IOException("Failed to read tile entity of block: <name>")

// after
try {
    SaveIO.load(file);
} catch (SaveException e) {
    Throwable c = e.getCause(); // may chain through "Error reading region map"
    while (c != null && c.getCause() != null) c = c.getCause();
    Log.err("Tile entity read failed for save @", file, c);
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try {
    SaveIO.load(file);
} catch (SaveException e) {
    Throwable c = e.getCause();
    while (c != null && c.getCause() != null) c = c.getCause();
    if (c != null && c.getMessage() != null && c.getMessage().startsWith("Failed to read tile entity")) {
        // block IO mismatch; report block name
    }
}

Prevention

When it happens

Trigger: Block class schema changed between save and load (added/removed serialized fields); modded block whose class is missing; corrupt entity byte stream causing ArrayIndexOutOfBounds / negative array size in readAll; revision byte does not match a known read revision of the block.

Common situations: Loading a save after updating the game and a block's serialization changed without a migration path; loading a modded save without the mod enabled; partial save corruption in the entities region; a custom block whose readAll implementation throws.

Related errors


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