Anuken/Mindustry · error · RuntimeException

Invalid array size:

Error message

Invalid array size: 

What it means

TypeIO.readObject() reads a Vec2[] (type 18). It reads a 2-byte (short) length and rejects it if it exceeds maxArraySize (1000, or 200 in the build-plan/safe=false path). The guard bounds memory use against a crafted packet.

Source

Thrown at core/src/mindustry/io/TypeIO.java:248

            //unit command
            case 15 -> {
                read.b();
                yield null;
            }
            case 16 -> {
                if(!allowArrays) throw new RuntimeException("Nested arrays are not allowed");
                int len = read.i();
                if(len > maxArraySize) throw new RuntimeException("Invalid array size: " + len);

                boolean[] bools = new boolean[len];
                for(int i = 0; i < len; i ++) bools[i] = read.bool();
                yield bools;
            }
            case 17 -> !box ? Groups.unit.getByID(read.i()) : new UnitBox(read.i());
            case 18 -> {
                if(!allowArrays) throw new RuntimeException("Nested arrays are not allowed");
                int len = read.s();
                if(len > maxArraySize) throw new RuntimeException("Invalid array size: " + len);

                Vec2[] out = new Vec2[len];
                for(int i = 0; i < len; i ++) out[i] = new Vec2(read.f(), read.f());
                yield out;
            }
            case 19 -> new Vec2(read.f(), read.f());
            case 20 -> Team.all[read.ub()];
            case 21 -> readInts(read);
            case 22 -> {
                if(!allowArrays) throw new RuntimeException("Nested arrays are not allowed");
                int len = read.i();
                if(len > maxArraySize) throw new RuntimeException("Invalid array size: " + len);

                Object[] objs = new Object[len];
                for(int i = 0; i < len; i++){
                    objs[i] = readObject(read, box, mapper, safe, false);
                }
                yield objs;

View on GitHub (pinned to f695ad7e60)

Solutions

  1. Cap Vec2[] length to <= 1000 (<= 200 via build-plan config) on the write side.
  2. Server-side: catch the RuntimeException and disconnect the sender.

Example fix

// before
writeObject(write, hugeVec2Array);

// after
Vec2[] trimmed = Arrays.copyOf(hugeVec2Array, Math.min(hugeVec2Array.length, 1000));
writeObject(write, trimmed);
Defensive patterns

Strategy: try-catch

Try / catch

try {
    Object obj = TypeIO.readObject(read);
} catch(RuntimeException e) {
    Log.err("Malformed Vec2[] packet", e);
    con.kick("Invalid packet data.");
}

Prevention

When it happens

Trigger: A type-18 packet whose short length field exceeds maxArraySize.

Common situations: Malicious/fuzzed client; a mod serializing a Vec2[] beyond the cap; the build-plan path where the limit is 200.

Related errors


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