JoinGG.cc
Features

Port Forwarding, NAT and CGNAT: Hosting a Game Server From Home

Your game server works locally but nobody can join. Diagnose it in order: bind address, OS firewall, router port forwarding, then CGNAT, and fix each one.

By SweetMask · · updated · 15 min read

Work through four layers in order and stop at the first failure: the server must listen on 0.0.0.0 rather than 127.0.0.1, the operating system firewall must allow the port, the router must forward the right protocol to a reserved LAN address, and your ISP must not be putting you behind CGNAT. The fourth one is unfixable by configuration.

Published 27 September 2026 · JoinGG · Guides

What "it works on my machine" actually proves

It proves the game server process started and bound to something. That is all. Connecting to localhost skips the network stack's routing, skips your router, and skips every device between you and your friend. Four distinct failures produce the identical symptom of a connection timeout, and people guess wrong about which one they have because all four look the same from the client side. Diagnose in layer order from the inside out: process, then host firewall, then router, then ISP. Each layer is cheaper to test than the one after it, and fixing layer three while layer one is broken teaches you nothing. The goal is a server as reachable as anything on the live server list, and the table below is the whole guide compressed.

That last row catches people who have done everything else right. Server lists and in-game browsers do not connect to your server, they query it, and the query often uses a different protocol or a neighbouring port. JoinGG's sweep works this way, polling every listed server hourly, which is why the measurement methodology is worth reading if your listing shows unreachable while people are visibly playing.

Check 1: is the server listening on 0.0.0.0?

A process that binds to 127.0.0.1 is reachable only from the machine it runs on. A process bound to 0.0.0.0 accepts connections on every interface the machine has. This is the cheapest possible failure to check and it is far more common than it should be, because several server distributions ship with a loopback default and several tutorials tell you to set one.

On Windows, run netstat -an | findstr 25565 in a terminal. On Linux, run ss -tulpn | grep 25565. You are looking at the local address column. If it reads 0.0.0.0:25565 or [::]:25565, this layer is fine and you should move on. If it reads 127.0.0.1:25565, you have found your problem and no amount of router configuration will help until it changes.

Where the setting lives per game

Test this properly before moving on. Take a second machine on the same WiFi, and connect to the server machine's LAN address with the port, for example 192.168.1.20:25565. If that works, layer one is done. If it does not, either the bind address is still wrong or you have already hit layer two. If you are setting a Minecraft server up for the first time, the walkthrough for running a Minecraft server for free covers the file layout this section assumes you already have.

Check 2: is the operating system firewall dropping it?

Windows Firewall blocks inbound connections on new ports by default, and it does so silently. There is no error in the server console, because the packet never arrives. This is the second most common cause after the bind address, and it has a specific trap that catches almost everyone: Windows applies different rules to Private and Public network profiles, and a fresh network connection often gets classified Public.

The reliable fix is an explicit inbound rule rather than clicking Allow on a popup you may have dismissed weeks ago. In an administrator PowerShell window:

Add -Profile Any if you want the rule to survive the network being reclassified. On Linux, the equivalent is sudo ufw allow 25565/tcp for Ubuntu-family systems or sudo firewall-cmd --permanent --add-port=25565/tcp followed by --reload on Fedora and RHEL. Check what is actually loaded with sudo ufw status verbose or sudo nft list ruleset, because a rule you added to the wrong zone is worth exactly nothing.

Two more things live at this layer. Third-party security suites often run their own firewall that ignores the Windows rules entirely, and if you have one installed you need to add the rule there too. And if the server runs inside Docker, WSL2 or a virtual machine, you have a second network boundary that behaves exactly like a second router. A container must publish the port to the host with -p 25565:25565/tcp, and forgetting the protocol suffix silently gives you TCP, which breaks every UDP game. WSL2 needs a port proxy on the Windows side, created with netsh interface portproxy add v4tov4 listenport=25565 connectaddress=<wsl-ip>, and the WSL address changes on every reboot unless you script it. A VirtualBox or Hyper-V guest on NAT networking needs its own forward in the hypervisor before the router forward can ever reach it. Test from another LAN machine after each boundary you cross, not once at the end.

Check 3: is the router forwarding the right protocol?

Your router performs network address translation. Every device in your house shares one public address, and the router keeps a table mapping outbound connections back to the device that made them. Inbound connections have no such entry, so unless you tell the router where to send them they are dropped. A port forwarding rule is that instruction, and four fields all have to be right: external port, internal port, internal address, and protocol.

The protocol field is where people lose hours. TCP and UDP are separate namespaces, so a UDP packet to port 19132 and a TCP connection to port 19132 are unrelated events. Forwarding TCP when the game needs UDP produces a completely invisible server while your rule looks correct in the interface. If you are unsure, create both. There is no cost to a forward the game never uses.

Reserve the LAN address first

Before creating the rule, give the server machine a DHCP reservation tied to its MAC address. Without one it picks up a new LAN address after a power cut, your rule still points at the old one, and you get the classic "it worked yesterday" failure with nothing in any log to explain it. A reservation beats a manually configured static IP because the router still knows the address is taken.

Double NAT, UPnP and the rules that expire

If your ISP supplied a modem-router and you added your own router behind it, you have two NAT layers and a forward on the inner router accomplishes nothing. The symptom is a WAN address on your router in the 192.168 or 10.x range. The fix is to put the ISP device into bridge or modem-only mode, or to create a matching forward on both devices. UPnP will create forwards automatically and is fine for an evening of play, but mappings expire, router mapping tables are small, and any program on your LAN can open a port without asking. For a server you plan to advertise, write the rule by hand. If you eventually list that server, the submission form needs an address that stays reachable, and an expiring UPnP mapping will not.

Why your own testing lies to you

NAT loopback, sometimes called NAT hairpinning, is a router feature that lets devices inside the network reach the public IP and get bounced back inward. Plenty of consumer routers do not implement it. When they do not, you type your public address from your own desktop, get a timeout, and conclude the forward failed, when in fact it works perfectly for everyone outside. Never test a forward from inside your own network. Use a phone with WiFi turned off, or ask someone else. Household players should always connect using the LAN address.

Check 4: are you behind CGNAT? The 30-second test

Carrier-grade NAT is the layer nobody warns you about, and it is the one that ends the project. IPv4 addresses ran out, so many ISPs now put hundreds or thousands of customers behind a single public address and run their own NAT table in front of everyone. From inside, browsing works normally. From outside, you do not exist as a destination. No router setting changes this, because the address your router thinks it owns is not visible on the internet.

The test takes half a minute. Open your router's status or WAN page and write down the IP it reports. Then look up your public address on any IP echo service. Compare the two.

Two further clues, if the address is ambiguous. A traceroute from your machine that shows several private hops before reaching anything routable indicates carrier NAT. And mobile broadband is behind CGNAT essentially universally, so if you are tethering or on a 5G home internet plan, you already have your answer and can skip straight to the next section.

This is worth checking before anything else if you are on fibre from a newer provider, on any mobile-based connection, or in a region where IPv4 has been scarce for years. Discovering CGNAT after three hours of firewall debugging is the standard experience, and it is entirely avoidable by spending thirty seconds up front.

What to do once you know you are behind CGNAT

You have four real options and one non-option. The non-option is more router configuration, which will not work no matter how many guides suggest it.

  1. Ask the ISP for a public IPv4 address. Often possible, sometimes free, sometimes a few dollars a month, occasionally only on a business tariff. Ask for a "public" or "routable" IPv4, not a "static" one, because those are different requests and support staff will answer the one you asked. Some providers have a self-service toggle in the account portal.
  1. Use IPv6. Most CGNAT deployments hand out a real IPv6 prefix, and IPv6 has no NAT: you open a firewall pinhole for the server's address instead of forwarding a port. Minecraft Java and Bedrock both handle IPv6 well. The catch is that any friend on an IPv4-only connection still cannot reach you, so treat it as a partial answer.
  1. Run a tunnel or relay. A small cloud instance with a public address, plus WireGuard back to your home machine and an iptables or nftables forward, gives your home server a public endpoint for a few dollars a month. Purpose-built tunnel services exist for Minecraft specifically. The cost is added latency, typically 10 to 40 ms depending on where the relay sits, and a dependency on a third party being up.
  1. Move the server to a VPS. Usually the right answer once you are past a handful of players. You get a public address, better upstream bandwidth, and no responsibility for your home network's exposure. Choose the region by where your players are rather than where you are, which the guide to picking a hosting region works through with real latency figures.

One honest note on home hosting even when it works. Residential upload bandwidth is the constraint people discover second. A Minecraft server sending state to 20 players uses roughly 2 to 5 Mbps upstream depending on how much of the world is changing, and a 40 Mbps upload link is comfortable. Source engine servers at high tickrate are hungrier per player. If your connection is asymmetric with 10 Mbps up, plan for a small private group rather than a public server, and expect the whole household's video calls to notice.

The exact ports each game needs

Defaults, protocols, and the query ports that server lists actually use. Forward the game port to play and the query port to appear in listings.

Three notes that save time. The Source engine family uses one port number for two different protocols and needs both, which is exactly the case where a TCP-only forward produces a server people can query but not join. FiveM's txAdmin panel on 40120 should never be exposed to the internet, so forward 30120 and nothing else. And the query behaviour differs by engine: Source uses the A2S protocol on the same UDP port as gameplay, while a listed Minecraft server answers a handshake on its TCP port and a Bedrock server replies to an unconnected ping over UDP. Anything monitoring your server, including the population statistics, depends on that query path being open. For FiveM specifically, the artifact version changes what the query endpoint returns, which the write-up on artifact updates and server queries covers in detail.

If you are not sure which port your build actually uses, do not trust the wiki. Read the console banner on startup, which every one of these servers prints, or run ss -tulpn on the host and forward whatever is really bound. Custom ports are fine and often sensible, but the query port has to move with the game port or your listing goes dark while players keep joining. That mismatch is common enough on GoldSrc that the Counter-Strike 1.6 population data, currently around 10,800 players across 1,588 servers, undercounts on any sweep where a batch of servers has firewalled its query path.

What opening a port at home actually exposes

A forwarded port is a hole in the only real boundary between your home network and the internet, and it will be found. Automated scanners sweep the entire IPv4 space continuously, and a newly opened 25565 typically attracts its first unsolicited connection within hours. Most of that traffic is harmless census scanning. Some of it is not.

The realistic risks, in the order they actually cause trouble:

Practical hardening that does not require expertise: use a non-default external port and map it to the standard internal one, which removes you from the noisiest scan lists. Turn on a whitelist for private servers, which the Minecraft beginner setup guide covers alongside the client-side steps your players will need. Keep automated offsite backups of the world, because ransomware aimed at game servers is a real category. And accept the honest conclusion: home hosting is excellent for a group of friends and a poor idea for a public server you intend to grow. Once you are advertising, a VPS costs less than the first incident.

Frequently asked questions

How do I know if I am behind CGNAT?

Open your router status page and read the WAN or internet IP. Then look up your public address on any IP echo service. If the two match, you have a public IP. If the router shows an address starting 100.64 through 100.127, or a 10.x, 172.16 to 172.31 or 192.168 address that is not your own second router, your ISP is carrying you through its own NAT and port forwarding cannot work.

Can I use UPnP instead of forwarding ports manually?

You can, and for a one-evening session it is fine. The problems are that UPnP mappings expire, that many routers ship with a small mapping table that silently drops the oldest entry, and that any program on your LAN can open a port without asking you. For a server you intend to advertise, write a static rule against a reserved LAN address instead.

Why can my friend join but not my brother in the same house?

That is NAT loopback, or rather the absence of it. Devices inside your network cannot reach your own public IP because the router will not send traffic back in through its own WAN interface. Have people on your LAN connect using the server machine's local address, such as 192.168.1.20 with the port, and leave the public address for people outside.

Do I need to forward TCP, UDP, or both?

It depends on the game and getting it wrong produces a server that half works. Minecraft Java is TCP only on 25565. Minecraft Bedrock is UDP only on 19132. Source engine games need both TCP and UDP on 27015, and FiveM needs both on 30120. When in doubt, forward both protocols on the same port number, since the extra rule costs nothing.

Is IPv6 a real answer to CGNAT?

Sometimes. Most ISPs that put you behind CGNAT still hand out a routable IPv6 prefix, and you can open a firewall pinhole for your server rather than forward a port. The limit is the game and the players. Minecraft Java and Bedrock handle IPv6 well, Source engine support is patchy, and any friend on an IPv4-only connection still cannot reach you.

What is the safest way to open a port at home?

Forward exactly one port to exactly one machine, run the server as an unprivileged user in a container or a virtual machine, keep the game binaries patched, and never expose RCON or a web panel to the internet. Put the server on a separate VLAN or guest network if your router supports it, and keep an offsite copy of the world.

Related reading

Once outsiders can reach your server, the next problem is that nobody knows it exists. JoinGG tracks 11,561 servers across the 31 games with servers currently online, polls each one hourly, and keeps seven days of history so you can see whether a change actually brought players in. Get the port open, confirm it answers a query from outside, then put the address somewhere people are already looking.

port forwardingcgnatnat loopbackgame server from homeminecraft port 25565bedrock 19132

More