#21348·tailscale

tailscale serve shared-service (svc:) routing silently breaks when xt_MARK kernel module is unavailable

Author: frankrossouwCreated Sep 17, 2026Updated Sep 17, 2026
LabelsOS-linuxservicespod/network-featuresdocker

Environment

  • Tailscale running as a Docker sidecar container (tailscale/tailscale image) on a NAS (vendor Linux firmware, non-mainline kernel)
  • Host kernel does not have the xt_MARK module available (modprobe xt_MARKmodule 'xt_MARK' not found)
  • Container advertises ~18 services via AdvertiseServices (Tailscale Services / svc: feature), each proxying to a different backend container on the same Docker network

What happens

On container start, the log shows:

wgengine: Reconfig: router config failed (adding [-i tailscale0 -j MARK --set-mark 0x40000/0xff0000] in v4/filter/ts-forward: running [/usr/sbin/iptables ...]: exit status 2: Warning: Extension MARK revision 0 not supported, missing kernel module?
...
); continuing to DNS config so name resolution still works

This is the same underlying defect as #8569 (iptables MARK rule failing silently, node/service still reported as configured/healthy) — but here it manifests through the svc: services feature rather than exit-node routing.

tailscale serve status correctly lists every service, e.g.:

https://myservice.<tailnet>.ts.net (tailnet only) (svc:myservice)
|-- / proxy http://myservice:3000

So the static configuration is correct. However, clients intermittently get connections refused, and the container log shows:

magicsock: disco: node [...] now using <ip>:<port>
The destination service doesn't have a TCP handler set.

This error reliably appears immediately after a peer's connection endpoint changes (visible via the preceding magicsock: disco line) — i.e., whenever a client's NAT mapping/roaming causes Tailscale to renegotiate the connection (common on WiFi/mobile clients; rare on a stable wired client). Wired clients on the same tailnet essentially never hit this because their endpoint rarely changes; WiFi/mobile clients hit it often.

Workaround found

The equivalent non-svc: per-port URL on the same node (e.g. https://<node>.<tailnet>.ts.net:3000) for the identical backend does not exhibit this failure and works reliably across the same endpoint-change events. This suggests the svc: routing path specifically depends on the MARK-based rule that failed at startup, while the plain per-node/per-port serve path does not.

Expected behavior

Per #4329, ideally Tailscale would detect the missing kernel module/failed iptables rule and either (a) refuse to advertise the affected svc: services as configured, or (b) fall back to a routing path that doesn't require MARK, rather than silently accepting new connections and failing them individually after the fact.

Related issues

  • #8569 (same MARK failure mode, exit-node context)
  • #4329 (feature request: detect required kernel modules)
  • #13863, #14018 (same xt_MARK/kernel module error on other distros)