Debugging User has disconnected, reason: Timed out
Tags: minecraft, logs, troubleshooting
Published: 2020-04-02 19:48:26

---
title: Debugging User has disconnected, reason: Timed out
published: true
description: How to get logs to aid in the troubleshooting of the `User has disconnected, reason: Timed out` message in Minecraft server logs.
tags: minecraft, logs, troubleshooting
---

Note: This is being approached from the side of the server operator, not the user.

There are many answers to how to troubleshoot the Minecraft `User has disconnected, reason: Timed out` message, they all boil down to "your internet is bad", "your server's tick is bad", your server is bad", `¯\_(ツ)_/¯`, or, even better, "I fixed it!" <sup>[4]</sup>

* My server has a great network connection, and is running at 20 TPS
* The user trying to connect has a 3-digit ping. Over 100, but not high enough to cause issues, imo.

What causes this error? There is actually only thing in Minecraft that can cause the exact `User has disconnected, reason: Timed out` message, and that is failure to receive a Keep Alive packet from the client in the expected time, or the other way around. <sup>[1]</sup>

Based on this, we would think this is probably a network issue. Unfortunately, by default, Minecraft does not output logs at a level lower then INFO. In order to troubleshoot, we need DEBUG level. How to get these?

Minecraft uses Log4j for logging. Thankfully, it is easy to override the configuration at runtime by passing a file containing new settings as part of the java arguments.

Let's start with the default log4j config <sup>[2]</sup> for Minecraft (this is the same for both client and server sides.

In order to change to DEBUG level, we need to edit `<Root level="info">` to `<Root level="debug">`. We also need to remove the `<filters>` section, which is dropping all network packets, regardless of level. Finally, since we are dealing with connection times, I've modified the timestamp to `%d{HH:mm:ss.SSS}`, to show milliseconds. 

Once you save your modified config file <sup>[3]</sup> somewhere, you need to tell Minecraft to use it. To do so, add the following option to your java command, `-Dlog4j.configurationFile=File:/home/drazisil/log4j_minecraft.xml`, changing the path to point to the full path and filename you chose.

I recommend trying this on the client who is having trouble first., assuming you can reproduce the issue, or they are willing to troubleshoot with you. You are looking for log lines like the following:

* `[14:16:40.945] [Netty Epoll Client IO #0/DEBUG]:  IN: [PLAY:21] ms`
* `[14:16:40.947] [Netty Epoll Client IO #0/DEBUG]: OUT: [PLAY:15] qb`

These are the packet ids, and the Minecraft class names. You can get the packet ids from https://wiki.vg

In this instance we can see that my client received the client-bound Keep Alive packet (21) at 14:16:40.945, and responded with a server-bound Keep Alive packet (15) at 14:16:40.947, 2 milliseconds later. Pretty good, so we know this isn't a client CPU issue. The next step would be to repeat the process on the server end and see if the server received the packet in that same time.

Hope this helps, and any questions or feedback, hit me up. (no, I will not help you troubleshoot individual cases) ;)

[1]: https://github.com/search?q=TranslationTextComponent%28%22disconnect.timeout%22%29&type=Code
[2]: https://gist.github.com/drazisil/e82b7dc151593dee4d0b4518958cea42
[3]: https://gist.github.com/drazisil/cfe81fe4cacf2500f465298a209f1cec
[4]: https://xkcd.com/979/