Anuken/Mindustry · warning · ValidateException

Player cannot configure a tile.

Error message

Player cannot configure a tile.

What it means

Thrown server-side as a ValidateException (RuntimeException) when a client's tile configure packet fails authorization: either Units.canInteract(player, build) is false, or netServer.admins.allowAction(configure) denies it. ValidateException carries the offending Player. It is not a bug; it is the anti-cheat/permission layer rejecting a packet. The server also sends a TileConfigCallPacket back to undo the client's local change.

Source

Thrown at core/src/mindustry/input/InputHandler.java:722

    @Remote(targets = Loc.both, called = Loc.both, forward = true)
    public static void tileConfig(@Nullable Player player, Building build, @Nullable Object value){
        if(build == null && net.server()) throw new ValidateException(player, "building is null");
        if(build == null) return;

        if(net.server() && (!Units.canInteract(player, build) ||
        !netServer.admins.allowAction(player, ActionType.configure, build.tile, action -> action.config = value))){

            if(player.con != null){
                var packet = new TileConfigCallPacket(); //undo the config on the client
                packet.player = player;
                packet.build = build;
                packet.value = build.config();
                player.con.send(packet, true);
            }

            if(!player.isLocal()){
                throw new ValidateException(player, "Player cannot configure a tile.");
            }else{
                return;
            }
        }
        if(player != null) build.updateLastAccess(player);
        build.configured(player == null || player.dead() ? null : player.unit(), value);
        Events.fire(new ConfigEvent(build, player, value));
    }

    //only useful for servers or local mods, and is not replicated across clients
    //uses unreliable packets due to high frequency
    @Remote(targets = Loc.both, called = Loc.both, unreliable = true)
    public static void tileTap(@Nullable Player player, Tile tile){
        if(tile == null) return;

        Events.fire(new TapEvent(player, tile));
    }

View on GitHub (pinned to f695ad7e60)

Solutions

  1. On the server, treat ValidateException as expected: log/handle it, do not crash. The net layer already undoes the client config.
  2. Ensure clients only send configure actions for buildings within Units.canInteract range and on their team.
  3. Review permission/admin rules if legitimate actions are being denied.
  4. If you write a custom server handler, catch ValidateException around remote invocations rather than letting it propagate.

Example fix

// before: client fires configure unconditionally
Call.tileConfig(player, build, value);

// after: client checks reachability first
if(Units.canInteract(player, build)){
    Call.tileConfig(player, build, value);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// client-side reachability check before sending configure
if(net.client() && !Units.canInteract(player, build)){
    return; // don't send a packet the server will reject
}

Try / catch

// server-side: ValidateException is expected for bad clients
try{ /* invoke remote configure */ }catch(mindustry.net.ValidateException e){ Log.debug("rejected configure from @", e.player); }

Prevention

When it happens

Trigger: A client sends a configure action (building.config change) for a tile it cannot reach/interact with, or that the server's admin rules forbid (e.g. outside build range, wrong team, permission denied). Server-side check in InputHandler.tileConfig; only thrown when !player.isLocal().

Common situations: A malicious/buggy client tries to configure a building out of range or on an enemy team; permission plugins deny configure; desync where the client thinks it can reach a tile the server says it can't.

Related errors


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