Your friends type in your address, and the game answers with a polite nothing. Chances are your internet line shares one IPv4 address with half the neighbourhood. Here is how to get everyone in anyway.
The short answer
A game server behind CGNAT or DS-Lite cannot be reached over IPv4 from the internet, because your router never receives a public IPv4 address of its own. A port forward in the router then leads nowhere [1][2]. Five ways around it are realistic: ask your provider for a public IPv4 address, use IPv6, share the server through Tailscale, relay the traffic through a rented VPS with WireGuard, or use a game relay service such as playit.gg. Which one fits depends on whether your friends will install something and on whether your game talks UDP. Cloudflare Tunnel is not on the list, because its documented service types contain no UDP [27].
The five ways at a glance
| Way | Friends install something? | UDP game ports | Main limit |
|---|---|---|---|
| 1. Public IPv4 from your provider | No | Yes, one rule per protocol | Provider must offer it, may cost extra |
| 2. IPv6 | No | Yes, one rule per protocol | Players and game need IPv6 |
| 3. Tailscale device sharing | Yes, client and account | Carried by the tunnel, test your game | Every player needs the client |
| 4. VPS relay with WireGuard | No | Yes, one forward per port | You rent and maintain a VPS |
| 5. Relay service (playit.gg) | No | Yes, UDP tunnels listed | A third party carries the traffic |
How it works
- Why the port forward fails. CGNAT (carrier-grade NAT) means your provider puts many customers behind one public IPv4 address. The block 100.64.0.0/10 is reserved for the links between the provider's NAT and its customers' routers [6]. DS-Lite (Dual-Stack Lite) reaches the same result differently: the FRITZ!Box wraps your IPv4 traffic in IPv6 and sends it to a provider device called AFTR, which shares IPv4 addresses among customers [7]. AVM states the consequence plainly: servers in the home network cannot be reached from the internet over IPv4 [2]. Your forward is correct. It just sits behind a second door that is not yours.
- Check which line you have. In the FRITZ!Box open Internet, Online Monitor, Connection Details, and read the lines "Internet, IPv4" and "Internet, IPv6". If no IPv4 address is shown, or one from 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.0.0.0/29 (DS-Lite tunnel) or 192.168.0.0/16, the box has no public IPv4 address. Any other IPv4 address means it has one [1]. If the Port Sharing page says that your provider makes certain ports available, the provider supports PCP (Port Control Protocol), and IPv4 works only on exactly those ports [1][2].
- TCP and UDP behave differently in a test. Minecraft Java Edition listens on TCP port 25565 by default, Bedrock Edition on UDP port 19132 [8]. A TCP port answers a connection attempt, so a check can tell open from closed and filtered [9]. A UDP port often stays silent, so a scanner can only report "open|filtered" [9]. The reliable UDP test is the real game client on a connection outside your home. Every way below ends with such a test.
- Test from outside, always. Use a phone on mobile data with Wi-Fi switched off, or a friend's connection. A test from inside your own network does not reliably prove a port sharing [12]. If you test over IPv6, open test-ipv6.com on the testing device first: not every mobile network or hotspot has IPv6 [1][2].
Way 1: ask your provider for a public IPv4 address
This is the cleanest fix. The classic port forward works again, and nobody has to install anything. You need a line with real dual stack: IPv4 and IPv6 side by side, with a public IPv4 address at the router. Whether your provider offers that, and for how much, differs by provider and tariff. One tutorial says it often costs a small monthly surcharge or is tied to a higher tariff [24]. A forum thread from 22 May 2025 reports a customer service agent adding a public IPv4 address for free [23]. We name no provider and no price, because we have no current source for either (unverified, as of 25 Oct 2026). After the switch, read the Online Monitor again and compare it with the ranges above [1]. Then create the rule: Internet, Permit Access, Port Sharing, Add Device for Sharing, New Sharing, "Other application", pick TCP or UDP and enter the port. A game that uses both gets one rule per protocol [3]. If the server has its own firewall, open the port there too [3]. A MyFRITZ! address keeps the box findable when the IPv4 address changes [3]. UDP is no problem on this way. Test: a TCP port from a host outside your network with nc -zv <your-IPv4> 25565 [11], a UDP port with the real client.
Way 2: use IPv6
A DS-Lite line always has IPv6, because the IPv4 tunnel runs over it [7]. A CGNAT line does not have to; AVM lists a line with IPv6 and IPv4 via CGNAT as reachable over IPv6 [1]. Every device gets its own globally valid address. The FRITZ!Box firewall blocks incoming connections until you open a port for a device [4][12]. Check IPv6 with test-ipv6.com on a device at home [1]. On the server, read the permanent global address with ip -6 addr show scope global -temporary, which hides the changing privacy addresses [13]. Then open Internet, Permit Access, Port Sharing, add the server, and create a sharing with IPv6 access, protocol and port. Check that the interface ID in the rule matches the server's real address [12]. Do not use the exposed host option: it opens the whole device, and AVM says to use it for testing only [5]. Two limits matter. First, AVM says an IPv6 connection to your home needs IPv6 on both sides, and that is not the case in every mobile network or hotspot [2]. Second, the game must listen on IPv6 and the client must use it. Bedrock servers have a separate setting for the IPv6 port, 19133 by default [14]. For other games, check the documentation; provider forums report services that only speak IPv4 [23]. Your provider can also change the IPv6 prefix, so use a dynamic DNS name with an AAAA record [12]. Test: from an IPv6-capable connection outside, nc -6 -zv <IPv6-address> 25565 for TCP, the real client for UDP.
Way 3: share the server through Tailscale
Tailscale builds an encrypted tunnel between devices. Your server connects outwards, so CGNAT does not matter. With node sharing you invite a friend to this one machine only, without exposing it to the public internet [10]. Shared machines are quarantined: they can answer connections but cannot start their own [10]. Sharing is available on all plans and does not increase your user count [10][15]. Each friend needs a Tailscale account and the client, then connects to the server's Tailscale address or name. Connections start through relay servers and then try to upgrade to a direct UDP connection; relayed ones are slower, and tailscale status and tailscale ping show which one you got [16]. The free Personal plan covers up to 6 users and is meant for non-commercial use (pricing page, 25 Oct 2026) [17]. Tailscale's access rules work per address and port [10]; whether your specific game's UDP ports pass is something to test, because we found no game list in the documentation. The limit is the client: some platforms, consoles in particular, may not let you install one, and we found no source that lists them. Unused invite links expire after 30 days [10]. Funnel is no substitute: it serves TLS-encrypted connections on ports 443, 8443 and 10000 only [18]. Test: the friend runs tailscale ping <server-name>, then joins.
Way 4: relay through a VPS with WireGuard
You rent a small VPS with a public IPv4 address. Your home server dials a WireGuard tunnel to it, and the VPS forwards the game ports into the tunnel. Outgoing connections work behind CGNAT [24], and WireGuard's persistent keepalive keeps the NAT mapping open [19]. Friends install nothing and connect to the VPS address. TCP and UDP both work (our assessment: destination NAT rules exist for both protocols [20]). The costs are a monthly VPS bill (no prices here, unverified), an extra network hop, and maintenance. Two side effects: with masquerading in the tunnel, the game server sees the VPS tunnel address instead of each player's address, so per-IP bans and limits stop working (our assessment); and if the VPS has a provider firewall, it must allow the game port and the WireGuard port, because such firewalls block inbound traffic by default [21][22]. A complete configuration follows in the example below. Test: sudo wg show wg0 latest-handshakes on both ends shows a handshake time [32], a TCP check from outside as in Way 1, and the real client for UDP.
Way 5: use a game relay service such as playit.gg
playit.gg runs an agent on the machine with your server. The agent connects outwards, players connect to an address on playit's servers, and the traffic runs down the agent's connection to your server [25]. The free tier lists Minecraft Java and Bedrock, Palworld, Valheim and custom UDP tunnels [25]. Free tunnels use global anycast routing, and the provider notes that a player in North America can be routed through Singapore; regional tunnels are a premium feature, as is raising the port count from 4 to 16 [26]. Premium costs $3 per month according to the site on 25 Oct 2026 [25]. The catch is trust and dependence: a third party carries every packet, and your group depends on its service. We have not tested other relay services and take no commission from any of them. Test: join with a game client from outside your network.
What does not work for UDP
Cloudflare Tunnel publishes hostnames for HTTP, HTTPS, Unix sockets, TCP, SSH, RDP and SMB; UDP is not among the documented service types, and non-HTTP services need cloudflared on every client [27]. Cloudflare's product for TCP and UDP is Spectrum. According to its plan table it is not available on the Free plan and is a paid add-on on Pro and Business, UDP applications are a paid add-on on Enterprise only, and a single Minecraft application is allowed from Pro upwards [28]. Spectrum combined with Tunnel works only for HTTP and HTTPS applications, and Bedrock is not supported [29]. So none of this solves a Bedrock server behind CGNAT.
A homelab example
We have not recorded which line type the Bytearium homelab uses (as of 25 Oct 2026), so this is a generic example for your own setup, not a report from ours. Take a Minecraft server with Java on TCP 25565 and Bedrock on UDP 19132 [8], and Way 4. First create a key pair on both machines [19]:
umask 077
wg genkey | tee privatekey | wg pubkey > publickeyOn the VPS, enable packet forwarding [30]:
sudo sysctl -w net.ipv4.ip_forward=1The setting is lost at reboot. To keep it, put the line net.ipv4.ip_forward=1 into a file under /etc/sysctl.d/, for example /etc/sysctl.d/99-forward.conf, which is read at boot [33]. Then write /etc/wireguard/wg0.conf on the VPS. Replace eth0 with the name of the VPS's public interface (shown by ip route show default):
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <VPS private key>
PostUp = iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25565 -j DNAT --to-destination 10.8.0.2:25565
PostUp = iptables -t nat -A PREROUTING -i eth0 -p udp --dport 19132 -j DNAT --to-destination 10.8.0.2:19132
PostUp = iptables -t nat -A POSTROUTING -o %i -j MASQUERADE
PostUp = iptables -A FORWARD -i eth0 -o %i -d 10.8.0.2 -j ACCEPT
PostUp = iptables -A FORWARD -i %i -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
PostDown = iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 25565 -j DNAT --to-destination 10.8.0.2:25565
PostDown = iptables -t nat -D PREROUTING -i eth0 -p udp --dport 19132 -j DNAT --to-destination 10.8.0.2:19132
PostDown = iptables -t nat -D POSTROUTING -o %i -j MASQUERADE
PostDown = iptables -D FORWARD -i eth0 -o %i -d 10.8.0.2 -j ACCEPT
PostDown = iptables -D FORWARD -i %i -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
[Peer]
PublicKey = <home server public key>
AllowedIPs = 10.8.0.2/32The PostUp and PostDown fields run commands when the interface goes up and down [31]. The DNAT and masquerade rules follow the destination NAT pattern of the nftables documentation, written here in iptables syntax [20]. On the home server, /etc/wireguard/wg0.conf looks like this. The keepalive of 25 seconds is the value WireGuard names as sensible for a wide variety of firewalls [19]:
[Interface]
Address = 10.8.0.2/24
PrivateKey = <home server private key>
[Peer]
PublicKey = <VPS public key>
Endpoint = <VPS public IP>:51820
AllowedIPs = 10.8.0.1/32
PersistentKeepalive = 25Bring the tunnel up on both machines with sudo wg-quick up wg0 [31] and set up start at boot as your distribution documents it. Allow UDP 51820, TCP 25565 and UDP 19132 in the VPS firewall. Then test from a phone on mobile data: join the Java server at the VPS address, and the Bedrock server with the VPS address and port 19132.
Checklist
- Read the Online Monitor and write down whether you have a public IPv4 address, an IPv6 address, or neither.
- Ask your provider what a public IPv4 address costs before you build anything else.
- Check test-ipv6.com on the testing device before you rely on IPv6.
- Create one port sharing per protocol and port, and never use the exposed host option for a game.
- Test every setup from outside your home network, and test UDP ports with the real game client.
- Decide whether your friends will install a client before you choose Tailscale.
- Allow the game port and the WireGuard port in the VPS firewall, and keep everything else closed.
- Watch the server log: after masquerading, every player shows up with the tunnel address.
- Read the terms of your VPS and relay provider before you route a public game server through them.