IPv6 neighbor discovery belongs to a link, and a routed tunnel is a boundary between two links. That one sentence explains almost every report of a remote host that answers by address and cannot be found by anything else. Check the scope of the address you are testing before you check the tunnel. A link-local address is meaningful only on its own link, and a solicited-node multicast group is scoped the same way. Neither crosses a router, which is why a ping to a global address can succeed while discovery for the same host does not.

Scope comes before configuration

Neighbor solicitation and advertisement carry a hop limit of 255 and are not forwarded, by design. The router between your tunnel and the remote LAN forwards IPv6 packets and does not relay neighbor messages on its behalf. So the neighbor cache on the tunnel interface contains the peer and little else, which is correct behaviour rather than a defect to fix.

A link-local address such as a fe80:: entry is also zone-scoped, and the same text can name a different host on a different link. Testing one from the other side of the tunnel proves nothing except that the address is ambiguous.

The trap is the on-link assumption

A host that believes a prefix is on-link sends a neighbor solicitation instead of handing the packet to its router, and that includes a /64 routed to a remote site. When such a prefix arrives as on-link, the host asks the local link for a host that lives elsewhere, and nothing answers. Route something smaller to the remote host, or terminate the prefix at the router that will answer for it.

A /128 for a single service is the least surprising arrangement, and it removes the ambiguity completely. The neighbor discovery specification describes the message set and the on-link flag that decides this.

Bridging changes the rules on purpose

When the tunnel carries Ethernet frames, the remote and local segments become one link, multicast reaches both sides, and neighbor discovery behaves as it would on a switch. The consequences arrive with it: broadcast and multicast flooding, duplicate address detection across the bridge, and router advertisements leaking into a segment that should not see them. The failure domain now spans two sites as well. None of that argues against bridging, and each point is a reason to bridge deliberately rather than incidentally.

Switching a profile from TUN to TAP to make discovery appear is the wrong order of operations. The server, client and addressing plan all have to agree, and mobile clients do not offer a TAP interface at all, so such a design works on a laptop and fails on a phone. Neighbor proxies and relays are separate mechanisms with their own requirements, and they belong to the network administrator's documented arrangement rather than to an app's settings.

Test with the address the application uses

Confirm the route with ip -6 route get, inspect the neighbor entry with ip -6 neigh, then confirm the service over the routed path. DNS and the return path are separate checks, and a healthy neighbor entry proves neither of them.

If the application insists on a link-local or discovery-based destination, that is a design conversation rather than a tuning exercise, because no client setting makes a link-scoped mechanism work across a router.

Write down which design you have

Record routed or bridged before the incident, since the two deployments answer these questions differently and an on-call engineer should not have to infer it from a profile.

Reading the message set once removes the temptation to explain a link-scope property as a VPN bug, which is the most expensive misdiagnosis in this area.

Related articles