Somebody runs a port check, sees the word open, and treats the server as solved. What that result actually means is narrow: from the checker's location, at that moment, a TCP connection to that address and port was accepted. It says nothing about the Minecraft protocol handshake, account authentication, or whether the server admitted the player into a world.

Those are four different layers, and a failure at any of them produces the same sentence from the player: it did not work.

A probe only tests what it can see

A TCP connection completes when both sides finish the three-way handshake, which is below anything the game knows about. The probe reports that a listener existed and responded from its network location. It cannot tell you that the listener is the game, because any process can bind a port and accept connections.

The location matters as much as the result. A checker on the public internet tests one path from one network. A checker run by the operator from inside the same network tests an entirely different path, and a positive result there says almost nothing about what a remote player experiences. Two different checkers on two different providers can even disagree for reasons that have nothing to do with your server.

Timing matters too. A probe result describes the moment it ran, and a home connection with a dynamic address or a changed forwarding rule can move the real answer a few minutes later. Record the public address, the port, the address family and the time along with the verdict, or the observation is not reproducible. Repeat the check from a genuinely different network rather than from a phone on the same connection.

Four layers between a socket and a player

Picture the sequence a joining client actually performs. First it resolves the address, then it opens a TCP connection to the published port, then it speaks the game's own protocol to negotiate and authenticate, and finally the server decides whether that identity is allowed into the world. Each layer has its own failure signature, and only the first one is visible to a port checker.

The default Java Edition port is 25565, but the operator may publish a different external port and forward it inward, so the number a player types is not necessarily the number the server sees. A checker aimed at the wrong external port reports closed while the server is perfectly healthy, which is the most common false alarm in this whole area.

Names add one more step above the port. If a player types a hostname, resolution has to return the published address, and on a machine inside the network it may return a private one instead. That is not a firewall failure and no amount of port forwarding will change it.

Why the inside player takes a different path

A player on the same LAN, or on a VPN that reaches that LAN, tries to reach the public address from inside. The request goes to the router's external address and the router has to translate it back inward, which is the arrangement usually called hairpinning or NAT reflection. Both the forward translation and the return path have to line up for that to work, and many consumer routers do not implement it at all.

This is why the outside guest joins and the person sitting next to the server cannot. The external path is genuinely fine; the internal detour is what fails, and it fails in a way that looks like a server problem from the player's screen. The server's own log settles which one happened, because a connection that was never translated never reaches it.

There are two honest fixes and one bad habit. The good options are to let internal players use the private address or a split-DNS name that resolves internally to the private address, or to enable reflection on the router if the feature exists and behaves. The bad habit is opening more ports or disabling the host firewall, which cannot affect a translation the router never performed.

The Netgate NAT reflection documentation describes the external-versus-inside distinction and the split-DNS alternative in more detail. Read it as a description of the mechanism rather than a promise that any particular VPN provider or router supports every loopback variant.

Collect evidence from each viewpoint

For each test, write down who ran it, from where, at what time, against which address and port, and what the server logged. A game rejection with a clear reason in the server console is a different finding from a connection that never arrived, and the two lead in opposite directions.

If permitted remote players join and one local player cannot, the local path is the remaining question and it deserves its own investigation: which address did the client use, what did the router do with the translation, and did the server record any connection attempt at all. Hand those three facts to whoever owns the network instead of reopening ports at random.

Ebitabo ebifaananyi