Anuken/Mindustry · warning · ValidateException

Player cannot control a unit.

Error message

Player cannot control a unit.

What it means

Thrown server-side as ValidateException in unitControl when possession is globally disabled (state.rules.possessionAllowed == false) or netServer.admins.allowAction(control) denies controlling the specific unit. Guards possession of AI units by players.

Source

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

    }

    @Remote(called = Loc.server)
    public static void unitBuildingControlSelect(Unit unit, Building build){
        if(unit == null || unit.dead()) return;

        //client skips checks to prevent ghost units
        if(unit.team() == build.team && (net.client() || build.canControlSelect(unit))){
            build.onControlSelect(unit);
        }
    }

    @Remote(targets = Loc.both, called = Loc.both, forward = true)
    public static void unitControl(Player player, @Nullable Unit unit){
        if(player == null) return;

        //make sure player is allowed to control the unit
        if(net.server() && (!state.rules.possessionAllowed || !netServer.admins.allowAction(player, ActionType.control, action -> action.unit = unit))){
            throw new ValidateException(player, "Player cannot control a unit.");
        }

        //clear player unit when they possess a core
        if(unit == null){ //just clear the unit (is this used?)
            player.clearUnit();
            //make sure it's AI controlled, so players can't overwrite each other
        }else if(unit.isAI() && unit.team == player.team() && !unit.dead && unit.playerControllable()){
            if(net.client() && player.isLocal()){
                player.justSwitchFrom = player.unit();
                player.justSwitchTo = unit;
            }

            //TODO range check for docking?
            var before = player.unit();

            player.unit(unit);

            if(before != null){

View on GitHub (pinned to f695ad7e60)

Solutions

  1. Server: catch/handle ValidateException as an expected rejection.
  2. Clients: gate possession requests on state.rules.possessionAllowed before calling.
  3. Verify the target unit is playerControllable() and on the player's team.
  4. Review admin/permission rules if valid possessions are rejected.

Example fix

// before
Call.unitControl(player, unit);

// after
if(state.rules.possessionAllowed && unit.playerControllable() && unit.team == player.team()){
    Call.unitControl(player, unit);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// client gates possession request
if(!state.rules.possessionAllowed){ return; }
if(unit != null && (!unit.playerControllable() || unit.team != player.team())){ return; }

Try / catch

try{ Call.unitControl(player, unit); }catch(mindustry.net.ValidateException e){ Log.debug("rejected unit control from @", e.player); }

Prevention

When it happens

Trigger: Client requests unitControl(unit) while state.rules.possessionAllowed is false, or the admin layer denies the control action for that unit. Server-side throw inside the @Remote handler.

Common situations: Server/gamemode forbids possession but a client tries anyway; permission plugin restricts which units may be controlled; anti-cheat rejects possession of disallowed units.

Related errors


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