Use of Rcon to execute commands that modify server state causes a race condition that may result in a java.util.ConcurrentModificationException
in the main server thread if a command modifies data during a server tick.
Conversely, executing commands via Rcon that iterate over internal data structures (such as /save-all
) may cause a java.util.ConcurrentModificationException
in the Rcon thread if the main thread modifies those structures (see MC-68374).
Update 2016-11-08
During reproduction of this bug, it was observed that introducing a small delay (as low as 0.003 seconds) between each command sent via rcon appears to greatly reduce the chance-per-command of the bug being triggered. However, with zero delay between commands being sent, the chance of the bug being triggered is significant, with usually less than 100 commands being enough to trigger the bug.
End update
In the following example, an external script was being used to run commands. A ConcurrentModificationException
was thrown when the Rcon thread /summon
ed a Creeper and added it to the world's entities list, while the main thread was simultaneously iterating over the same list due to a command block executing /kill @e[type=MinecartTNT]
. (Full crash report is attached)
[2014-09-26 21:14:21] [RCON Client #3/INFO]: $SERVCMD Rcon: effect RobotoRaccoon 11 60 100 true
[2014-09-26 21:14:21] [RCON Client #3/INFO]: [Rcon: Given Resistance (ID 11) * 100 to RobotoRaccoon for 60 seconds]
[2014-09-26 21:14:21] [RCON Client #3/INFO]: $SERVCMD Rcon: playerinfo RobotoRaccoon
[2014-09-26 21:14:21] [RCON Client #3/INFO]: $SERVCMD Rcon: summon Creeper 2209 86 501 {Fuse:0}
[2014-09-26 21:14:21] [RCON Client #3/INFO]: [Rcon: Object successfully summoned]
[2014-09-26 21:14:21] [Server thread/ERROR]: Encountered an unexpected exception
u: Executing command block
at net.minecraft.server.MinecraftServer.z(SourceFile:603) ~[minecraft.jar:?]
at po.z(po.java:228) ~[minecraft.jar:?]
at net.minecraft.server.MinecraftServer.y(SourceFile:531) ~[minecraft.jar:?]
at net.minecraft.server.MinecraftServer.run(SourceFile:447) [minecraft.jar:?]
at java.lang.Thread.run(Unknown Source) [?:1.7.0_55]
Caused by: java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source) ~[?:1.7.0_55]
at java.util.ArrayList$Itr.next(Unknown Source) ~[?:1.7.0_55]
at aqu.a(SourceFile:2230) ~[minecraft.jar:?]
at ah.a(SourceFile:433) ~[minecraft.jar:?]
at ah.b(SourceFile:136) ~[minecraft.jar:?]
at ab.a(ab.java:71) ~[minecraft.jar:?]
at aqf.a(SourceFile:97) ~[minecraft.jar:?]
at auo.b(SourceFile:53) ~[minecraft.jar:?]
at qt.a(SourceFile:527) ~[minecraft.jar:?]
at qt.c(SourceFile:199) ~[minecraft.jar:?]
at net.minecraft.server.MinecraftServer.z(SourceFile:599) ~[minecraft.jar:?]
... 4 more
[2014-09-26 21:14:21] [Server thread/ERROR]: This crash report has been saved to: /data/minecraft/18-temp/./crash-reports/crash-2014-09-26_21.14.21-server.txt
[2014-09-26 21:14:21] [RCON Client #3/INFO]: $SERVCMD Rcon: summon Creeper 2209 87 501 {Fuse:0}
[2014-09-26 21:14:21] [RCON Client #3/INFO]: [Rcon: Object successfully summoned]
Reproduction
Create a new Minecraft server instance.
Enable Rcon on the default port (25575)
Set Rcon password to "test"
Connect a Minecraft client to the server.
Move the player to x=0, z=0 (or use
/spreadplayers 0 0 1 1 false @a
) to ensure this location is loaded.Use Python to run the attached rcon.py script, which will send commands to the server (spawning entities at x=0 z=0)
The server should crash in under 60 seconds (usually only a few seconds).
I have successfully reproduced a ConcurrentModificatonException
crash using this method. Due to the nature of this bug (race condition), it may take some time before the crash occurs.
Linked issues
is duplicated by 6
relates to 3
Attachments
Comments 38
Minecraft Crash Report ----
// Shall we play a game?
Time: 10/10/14 11:04
Description: Exception in server tick loop
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
at java.util.HashMap$KeyIterator.next(HashMap.java:1453)
at qn.a(SourceFile:166)
at net.minecraft.server.MinecraftServer.z(SourceFile:615)
at po.z(SourceFile:305)
at net.minecraft.server.MinecraftServer.y(SourceFile:531)
at net.minecraft.server.MinecraftServer.run(SourceFile:447)
at java.lang.Thread.run(Thread.java:745)
A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------
– System Details –
Details:
Minecraft Version: 1.8
Operating System: Linux (amd64) version 2.6.32-042stab092.1
Java Version: 1.8.0_20, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 2473019160 bytes (2358 MB) / 6242500608 bytes (5953 MB) up to 10522722304 bytes (10035 MB)
IntCache: cache: 0, tcache: 0, allocated: 12, tallocated: 94
Profiler Position: N/A (disabled)
Is Modded: Unknown (can't tell)
Type: Dedicated Server (map_server.txt)
Minecraft Crash Report ----
// Shall we play a game?
Time: 10/10/14 21:58
Description: Exception in server tick loop
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
at java.util.HashMap$KeyIterator.next(HashMap.java:1453)
at qn.a(SourceFile:166)
at net.minecraft.server.MinecraftServer.z(SourceFile:615)
at po.z(SourceFile:305)
at net.minecraft.server.MinecraftServer.y(SourceFile:531)
at net.minecraft.server.MinecraftServer.run(SourceFile:447)
at java.lang.Thread.run(Thread.java:745)
A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------
– System Details –
Details:
Minecraft Version: 1.8
Operating System: Linux (amd64) version 2.6.32-042stab092.1
Java Version: 1.8.0_20, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 1308330000 bytes (1247 MB) / 4080271360 bytes (3891 MB) up to 10522722304 bytes (10035 MB)
IntCache: cache: 0, tcache: 0, allocated: 12, tallocated: 94
Profiler Position: N/A (disabled)
Is Modded: Unknown (can't tell)
Type: Dedicated Server (map_server.txt)
Minecraft's rcon implementation is nothing but a quick hack. Every shortcut that doesn't prevent it from working at all was taken. You may remember MC-87863 as well. I say they should just rewrite it from scratch. They wouldn't be throwing much away anyway.
Unfortunately, setting a 0.003 second delay is not a sufficient workaround to stop our hourly world backup script from occasionally crashing the server.
Attached Python script used to reproduce the bug. Connects to Rcon on port 25575 with password "test" and issues a rapid series of
/summon Fireball
commands (server despawns the fireballs immediately).