mojira.dev
MC-313098

Parallel RCON connections receive each other's command output

All RCON connections share one output buffer. When two RCON connections run commands at the same time, a reply can contain the other connection's output, contain both outputs joined together, or be empty. The commands themselves run correctly; only the replies are wrong.

No misbehaving client is needed: two clients that each send one command at a time and wait for each reply are enough, for example two separate tools connected to the same server.

Steps to Reproduce

  1. Start a dedicated server with these lines in server.properties:

    enable-rcon=true
    rcon.port=25575
    rcon.password=test
  2. Open two RCON connections and authenticate both.

  3. In a loop, send seed on connection A and list on connection B, at the same time. Each connection waits for its reply before sending the next command.

  4. Check each reply: replies on A should start with Seed: , replies on B with There are .

The attached RconSharedBuffer.mjs does this (Node.js, no dependencies):

node RconSharedBuffer.mjs 127.0.0.1 25575 test 10      # two connections
node RconSharedBuffer.mjs 127.0.0.1 25575 test 10 1    # control: one connection

Observed Results

On 26.3, 10 seconds each:

  • Two connections: 492,208 replies, 54.5% wrong:

    • 131,083 with the other command's output

    • 74,489 with both outputs

    • 62,529 empty

  • One connection (control), same commands alternating: 278,898 replies, none wrong.

Expected Results

Each RCON connection receives exactly the output of its own command.

Code Analysis

Based on the 26.3 and 26.4-snapshot-7 server jars:

  • DedicatedServer.runCommand(String) calls rconConsoleSource.prepareForCommand(), which clears the buffer with StringBuffer.setLength(0); then runs the command on the main thread with executeBlocking(...); then returns rconConsoleSource.getCommandResponse().

  • rconConsoleSource is a single field of DedicatedServer, and RconConsoleSource holds one StringBuffer.

  • Every RconClient thread calls runCommand, so one connection's prepareForCommand() can clear another connection's output, and the outputs of both commands land in the same buffer.

Creating an RconConsoleSource per runCommand call would fix it.

Notes

  • The same behaviour was measured on 1.20.1 and 1.16.5.

  • Related: MC-87863 (RCON uses TCP as though it's datagram-based).

Environment

vanilla dedicated server, macOS, Java 25.0.5. The cause is in platform-independent server code (see Code analysis).

Attachments

Comments 1

Thank you for helping us improve Minecraft! We saved your files:

[media]

Janis Pritzkau

(Unassigned)

Unconfirmed

26.4 Snapshot 7

Retrieved