MikroTik WireGuard connected, no internet
A RouterOS 7 WireGuard tunnel can handshake and still carry nothing. Route tables from a CHR lab run show the three causes and the command that names each.
Key takeaways
- 3 independent causes make a RouterOS 7 WireGuard tunnel show a handshake and still fail: a missing or self-defeating route, a missing masquerade on the way out, and a packet size the path will not carry in full.
- allowed-address=0.0.0.0/0 added no default route in the lab run: the only default route was still wan-default, and the far end counted 0 internet-host pings through the tunnel.
- A default route through wg-lab with no route to the endpoint made /ip/route/check name wg-lab as the way to the endpoint, and the last handshake aged to 3m13s while received bytes stayed at 412.
- One /32 route to the endpoint through the WAN gateway brought the handshake back within 12 s; a router-sourced ping from the LAN address needed the srcnat masquerade out of wg-lab as well.
On this page (8)
- How was the lab run set up, and what does it not cover?
- Why is a MikroTik WireGuard tunnel up with no internet?
- Does allowed-address 0.0.0.0/0 add a route in RouterOS?
- Why does the tunnel die after I add a default route through it?
- How do you route everything through a RouterOS WireGuard tunnel without losing the handshake?
- Could packet size, MSS clamping or FastTrack be why a MikroTik tunnel stalls?
- What changes if the tunnel is the ForestVPN container?
- How do you get the router back if you cut off its own tunnel?
A recent handshake with no traffic on RouterOS 7 usually means one of three faults: a route, a NAT or a size problem. We reproduced the first two on a virtual router and show the tables.
NAT here means masquerade, a rule that rewrites the source address of packets leaving through an interface. A route problem often starts with allowed-address, the peer setting that lists which addresses may pass through the tunnel.
The threads in the search results end at "add masquerade" or at a licence limit, which one poster reports on a cloud router as the cause in their case. None of those we read shows the route table before and after. Here are both tables.
How was the lab run set up, and what does it not cover?
A CHR (Cloud Hosted Router) is MikroTik's virtual RouterOS image, and this run used one, not a hardware router. Every code block below comes from this run. Read the box first.
How this was tested
- Product
- MikroTik RouterOS 7 native WireGuard interface
- Version
- 7.24.1 (stable), CHR arm64, free licence
- System
- RouterOS 7 on QEMU in software emulation
- Checked
- Runs
- 1
Not tested
Two CHR guests on one host: R1 is the router under test and R3 is the WireGuard peer, linked by one virtual cable. Addresses are documentation ranges: 192.0.2.0/24 for the WAN link, 203.0.113.2 for the peer endpoint, 10.99.0.0/24 for the tunnel and 192.168.88.0/24 for the LAN. The "internet host" 198.51.100.1 belongs to R3, so R3 packet counters show whether a ping arrived over the WAN link or through the tunnel. The peer accepts only 10.99.0.2/32 from R1. Each state was captured once; timings in milliseconds are emulation and are not a result.
Not tested: hardware boards, RouterOS 6, other 7.x versions, mangle (rules that mark packets for routing) or routing-mark setups, a forwarded LAN client (the LAN-sourced test is a router-originated ping with a LAN source address), a DNS failure, a no-handshake input-chain case, MSS clamping, FastTrack (a RouterOS shortcut that skips firewall rules for established connections), the ForestVPN container client. A packet-size blackhole was not reproduced.
Why is a MikroTik WireGuard tunnel up with no internet?
A WireGuard handshake only proves the two ends agreed on keys, and RouterOS adds no route for allowed-address and no NAT rule when it comes up. The table pairs each symptom with one check and one fix; <endpoint-address> and <far tunnel address> are the values from your own peer.
| What you see | Check | Likely cause | Fix |
|---|---|---|---|
| Tunnel address answers, other traffic still works but leaves by the WAN | /ip/route/print where dst-address=0.0.0.0/0, then /ip/route/check <internet address> | No route into the tunnel | Add a route with the WireGuard interface as gateway |
| Handshake ages out after you add a default route through the tunnel | /ip/route/check <endpoint-address> | The endpoint's own packets enter the tunnel | Add a /32 route to the endpoint through the WAN gateway |
| Tunnel address answers, anything with a LAN source address does not | /ip/firewall/nat/print | No masquerade out of the tunnel | Add srcnat masquerade with out-interface set to the WireGuard interface |
| Small requests pass, large transfers stall | /ping <far tunnel address> size=1420 do-not-fragment | Packet size. A silent loss means a limit in the path; a local "packet too big" means the interface MTU | Lower the interface MTU, or clamp MSS on tunnelled TCP; the ForestVPN app shows the same symptom as Small packets pass, large ones don't |
| Clients of the router reach its tunnel address but names do not resolve | /ip/firewall/filter/print where chain=input | Input chain drops the WireGuard subnet. Not run; from the RouterOS docs | Accept the WireGuard subnet in the input chain before the drop rules; the forward chain may need an accept as well |
| No handshake at all | /interface/wireguard/peers/print | Input chain drops the UDP port. Not run | Accept the listen port in the input chain before the drop rules, as the RouterOS docs say |
The rows are in the order we would check them once a handshake exists. Of the six, the first three are what the run reproduced; the size case was tried and not reproduced, and the last two were not run, as the box above says.
Does allowed-address 0.0.0.0/0 add a route in RouterOS?
No. In this run the peer carried allowed-address=0.0.0.0/0 and the route table gained nothing. After the handshake came up, R1 held the WAN default and four connected networks, and a ping of the tunnel address worked.
(trimmed)
> /interface/wireguard/peers/print detail
...
endpoint-address=203.0.113.2 endpoint-port=51820
current-endpoint-address=203.0.113.2 current-endpoint-port=51820
allowed-address=0.0.0.0/0 persistent-keepalive=5s client-endpoint=""
client-allowed-address="" rx=92 tx=244 last-handshake=12s
> /ip/route/print
# DST-ADDRESS GATEWAY ROUTING-TABLE DISTANCE
;;; wan-default
0 As 0.0.0.0/0 192.0.2.2 main 1
DAc 10.0.2.0/24 mgmt main 0
DAc 10.99.0.0/24 wg-lab main 0
DAc 192.0.2.0/24 wan main 0
DAc 192.168.88.0/24 lan main 0The trap hides in the next test. A ping of the "internet host" 198.51.100.1 also succeeded, three of three, and it looks like proof. It was not.
R3's counters match any ICMP to 198.51.100.1, and they read six over the WAN link and none through the tunnel: the three plain pings plus the three LAN-sourced pings of the same script, which went out the WAN as well. The WAN default route carried all six. A working ping shows only that some path exists, not that it is the one you wanted.
Allowed-address on a RouterOS peer is a filter on what the peer may send and receive, and the RouterOS documentation writes routes separately with /ip/route. If you want the tunnel to carry traffic, you say so in the route table.
Why does the tunnel die after I add a default route through it?
A default route through the tunnel also captures the tunnel's own encrypted packets, because they match it too. We added a second default route with gateway wg-lab at distance 1 and moved the WAN default to distance 2.
(trimmed)
> /ip/route/print where dst-address=0.0.0.0/0
# DST-ADDRESS GATEWAY ROUTING-TABLE DISTANCE
;;; wan-default
0 s 0.0.0.0/0 192.0.2.2 main 2
;;; default-via-tunnel
1 As 0.0.0.0/0 wg-lab main 1The ping of the tunnel address, which worked just before, timed out three of three straight away. Left alone, the peer record aged out: after 3m13s there was still no new handshake.
Transmit bytes kept growing while received bytes sat at 412 from the first capture to the last. The router kept sending and heard nothing.
Ask the router which way it would send a packet to the peer's endpoint-address:
(trimmed)
> /ip/route/check 203.0.113.2
status: ok
interface: wg-lab
nexthop: 203.0.113.2Its way to the endpoint is the tunnel interface. The packets the interface produces, once encrypted, are addressed to that endpoint, and the router sends them back into the interface. That is a loop, and it is consistent with what the counters showed, though the run did not capture the packets themselves.
How do you route everything through a RouterOS WireGuard tunnel without losing the handshake?
Add one /32 route for the endpoint through the WAN gateway, and add a masquerade for what leaves through the tunnel. In the run the first fixed the handshake and the second fixed LAN-sourced traffic.
(trimmed)
> /ip/route/add dst-address=203.0.113.2/32 gateway=192.0.2.2 comment=endpoint-via-wan
> /ip/route/check 203.0.113.2
status: ok
interface: wan
nexthop: 192.0.2.2Within 12 s of the endpoint route being in place the handshake was back, and both pings, to the tunnel address and to 198.51.100.1, worked.
A third ping used the router's LAN address as its source, standing in for a LAN client's packet. Three of three timed out, because the peer accepts only 10.99.0.2/32 from R1.
(trimmed)
> /ping 198.51.100.1 count=3 src-address=192.168.88.1
sent=3 received=0 packet-loss=100%
> /ip/firewall/nat/add chain=srcnat action=masquerade out-interface=wg-lab
> /ping 198.51.100.1 count=3 src-address=192.168.88.1
sent=3 received=3 packet-loss=0%The masquerade rewrites the source to the tunnel address on the way out, and the same ping then returned three of three. After a counter reset, the R3 counters read six packets through the tunnel and zero over the WAN link for the six pings (the three plain and three LAN-sourced pings to 198.51.100.1), which is the proof the earlier ping lacked. This is router-originated traffic with a LAN source, not a forwarded client, so treat it as the NAT half of the story and test with a real LAN device before you trust it.
Could packet size, MSS clamping or FastTrack be why a MikroTik tunnel stalls?
We tried to produce a size blackhole and could not; MSS and FastTrack were not exercised. The WireGuard interface MTU 1420 is the default in the RouterOS documentation, and in the run a do-not-fragment ping of size 1420 passed while 1421 was refused locally, as "packet too big".
Next, the WAN link MTU went down to 1400 on both routers with the interface MTU still 1420, and we expected a blackhole. None came.
Do-not-fragment pings of 1420 still passed, which is consistent with the outer packets being fragmented, though we took no capture to confirm it. With the interface MTU at 1320, a do-not-fragment ping of 1400 was refused locally.
The useful part is that RouterOS tells you at once when a ping is larger than the interface MTU.
A silent loss is what an in-path limit produces when the reply never arrives: under RFC 1191 a router that drops a do-not-fragment packet also returns an ICMP "fragmentation needed" message, and the loss is silent only when that message does not get back to the sender. Our general troubleshooting article covers the app-side version of that symptom.
MSS clamping and FastTrack
For TCP, the choose-traffic page adds a mangle rule with change-mss and clamp-to-pmtu for tunnelled connections, and says that without it large TCP flows stall. FastTrack skips mangle. If you mark traffic for a tunnel with mangle rules, keep the marked connections out of FastTrack, which is the same warning that page gives for the ForestVPN container.
What changes if the tunnel is the ForestVPN container?
The ForestVPN router client on a MikroTik is a RouterOS 7 container, not a native WireGuard interface, and the image is suquant/fvpn, set up from the setup page. By default it tunnels only the router's own traffic. Sending LAN traffic through it takes RouterOS mangle rules and a routing table on the box that routes your LAN, as the choose-traffic recipes walk through. ForestVPN does not issue a native WireGuard configuration for the routes in this article.
A form of the same loop exists here: if the container's own packets get marked for the tunnel, the tunnel is routed into itself. The "everything" recipe prevents it by excluding the container's address from marking. Check the route table first, then the counters.
If you also want rules that make selected LAN traffic stop when the container is down, the kill switch page has them, and it says plainly that the whole stop-and-test has not been run on a router.
To compare the two router recipes, see MikroTik vs OpenWrt as a VPN router, and for the measured speed of the tunnel core on two physical MikroTik routers, the throughput post.
How do you get the router back if you cut off its own tunnel?
Keep a path to the router that does not use the tunnel, then add the endpoint route or disable the tunnel default route. The lab router had a separate management interface, which is why the 3m13s stall could be inspected over SSH while the tunnel was starved.
Two edits recover it: add the /32 endpoint route, or disable the route you added with gateway wg-lab. Do either one over that separate path, never over the tunnel you are repairing. The endpoint route brought the handshake back within 12 s in the run; we did not try disabling the tunnel default route.
Questions and answers
Why is my MikroTik WireGuard tunnel up but I have no internet?
A handshake only proves the two ends agreed on keys. Traffic still needs a route into the tunnel, a route to the peer's endpoint that does not go through the tunnel, a masquerade for LAN source addresses, and packets small enough for the path. The checks are /ip/route/check for the endpoint, /ip/route/print for the default route, /ip/firewall/nat/print for the masquerade and a do-not-fragment /ping for size.
Does allowed-address 0.0.0.0/0 add a route in RouterOS?
Not in the lab run on RouterOS 7.24.1. With the peer set to 0.0.0.0/0 the route table held only the WAN default and the connected networks. You add the default route yourself, for example a route with gateway wg-lab.
Why does the tunnel stop working after I add a default route through it?
If the router has no separate route to the peer's endpoint, the encrypted packets for the endpoint follow the new default route into the tunnel itself. In the run, /ip/route/check for the endpoint reported the tunnel interface and the handshake aged out. A /32 route to the endpoint through the WAN gateway fixed it.
Do I need a masquerade rule on the WireGuard interface?
When the traffic leaving the tunnel carries an address the peer does not accept, yes. In the run, the peer accepted only the tunnel address, a ping with the LAN address as source got no reply, and it worked after a srcnat masquerade with out-interface wg-lab.
Why do some sites load and others stall on a MikroTik tunnel?
Stalls on large transfers while small requests pass point at packet size. The WireGuard interface MTU defaults to 1420 on RouterOS. The run did not reproduce a size blackhole, so it can tell you how to test, not what you will see.
How do I get the router back if I cut off its own tunnel?
Keep a way in that does not use the tunnel, such as a separate management interface. Then add the endpoint route, or disable the default route through the tunnel. The lab captures were taken over SSH on a separate management interface, not through the tunnel.
Sources
- MikroTik documentation: WireGuard (RouterOS) (read October 16, 2026)
- RFC 1191: Path MTU Discovery (read October 16, 2026)
- Serverfault: WireGuard on MikroTik, no internet connection (read October 16, 2026)
How this was made
Drafted with AI assistance from a lab run on a virtual RouterOS 7.24.1 router, checked by automated gates and an editor; the run used documentation addresses and throwaway keys.