MuntashirAkon/AppManager · error · IOException

Invalid message length:

Error message

Invalid message length: 

What it means

readMessage() reads a 4-byte length prefix and validates it before allocating; a negative length or one exceeding MAX_MESSAGE_SIZE indicates a corrupted or desynchronized frame, so it throws IOException("Invalid message length: " + len). This prevents huge or nonsensical allocations from untrusted input.

Solutions

  1. Verify both ends use the same DataTransmission framing/protocol version
  2. Ensure every sendMessage is flushed and lengths written on frame boundaries; resync or restart the connection on error
  3. Validate/sanitize any untrusted input before sending to keep frames well-formed
  4. Catch the IOException and re-establish the session (re-run shakeHands)

Example fix

// before
byte[] msg = transmission.sendAndReceiveMessage(request);
// after
byte[] msg;
try {
    msg = transmission.sendAndReceiveMessage(request);
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Invalid message length")) {
        transmission = recreateAndHandshake();
        msg = transmission.sendAndReceiveMessage(request);
    } else throw e;
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    byte[] msg = transmission.sendAndReceiveMessage(request);
} catch (IOException e) {
    // Invalid message length: connection is desynchronized; re-establish session
    transmission = recreateAndHandshake();
}

Prevention

When it happens

Trigger: The peer sends malformed frames: stream desynchronization (offset misalignment after a failed write), a corrupted length header, a hostile client/server sending garbage, or reading with a stale/different framing version.

Common situations: Protocol version mismatch between client and server; data written without flush causing byte misalignment; MITM or injected garbage on the socket; reading after the peer died mid-frame.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/4540d76c2e21f162. Report an issue: GitHub.

Appendix: source

Thrown at libserver/src/main/java/io/github/muntashirakon/AppManager/server/common/DataTransmission.java:137

                throw new IOException("Message is too large: " + messageBytes.length);
            }
            mOutputStream.writeInt(messageBytes.length);
            mOutputStream.write(messageBytes);
            mOutputStream.flush();
        }
    }

    /**
     * Read response as bytes after sending a message
     *
     * @return The bytes to be read
     * @throws IOException When it fails to read the message
     */
    @NonNull
    private byte[] readMessage() throws IOException {
        int len = mInputStream.readInt();
        if (len < 0 || len > MAX_MESSAGE_SIZE) {
            throw new IOException("Invalid message length: " + len);
        }
        byte[] bytes = new byte[len];
        mInputStream.readFully(bytes, 0, len);
        return bytes;
    }

    /**
     * Send and receive messages at the same time (half-duplex)
     *
     * @param messageBytes Bytes to be sent
     * @return Bytes to be read
     * @throws IOException When it fails to send or read the message
     * @see #sendMessage(String)
     * @see #sendMessage(byte[])
     */
    @NonNull
    public synchronized byte[] sendAndReceiveMessage(@NonNull byte[] messageBytes) throws IOException {
        sendMessage(messageBytes);

View on GitHub (pinned to 0152f468fc)