[GH-ISSUE #5734] UDP Services Generating TCP nftables rules on Routing Peers #11701

Open
opened 2026-08-05 01:30:33 -04:00 by saavagebueno · 1 comment
Owner

Originally created by @SamFusco on GitHub (Mar 30, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5734

Describe the problem
When exposing a service through the NetBird reverse proxy using UDP (e.g. udp://192.168.1.2:56789), the routing peer generates nftables forwarding rules using tcp dport instead of udp dport. This means UDP packets arriving on the routing peer via the WireGuard tunnel (wt0) are silently dropped and never forwarded to the destination.

To Reproduce

  1. Create a service in Networks → Services pointing to a UDP destination e.g. udp://192.168.1.2:56789
  2. On the routing peer, run sudo nft list ruleset | grep 56789
  3. Notice the generated rule uses tcp dport 56789 despite the service being configured as UDP

Expected behavior
The generated nftables rule in the netbird-rt-fwd chain should use udp dport when the service is configured with a udp:// destination. Instead it always generates tcp dport regardless of the protocol specified.

Are you using NetBird Cloud?
Self-hosted

NetBird version
0.67.1

Is any other VPN software installed?
No

Debug output
sudo nft list ruleset | grep -A2 "56789"
Output showing tcp dport instead of udp dport.
And the tcpdump showing packets arriving on wt0 but never leaving on enp6s18:

23:15:32.874718 wt0   In  IP 100.94.56.138.35335 > 192.168.1.2.56789: UDP, length 148
23:15:37.945205 wt0   In  IP 100.94.56.138.35335 > 192.168.1.2.56789: UDP, length 148

UDP relay added in the Proxy

2026-03-30T12:31:08.243Z INFO [listen_port: 443, service_id: d756q37dqmns73fnnl2g, target: 192.168.1.2:56789] proxy/server.go:1401: UDP relay added

nftable rule generated

ip saddr 100.94.56.138 ip daddr 192.168.1.0/24 tcp dport 56789-56789 counter packets 0 bytes 0 accept
ip saddr 100.94.175.191 ip daddr 192.168.1.0/24 tcp dport 56789-56789 counter packets 0 bytes 0 accept
ip saddr 100.94.116.185 ip daddr 192.168.1.0/24 tcp dport 56789-56789 counter packets 0 bytes 0 accept

Screenshots
Just the GUI udp service

Additional context
Took a while to track this one down. Traffic was making it through Netbird-proxy → WireGuard tunnel fine, but dying on the routing peer. tcpdump on wt0 showed packets arriving, but nothing ever appeared on the physical interface. Only after inspecting the nftables ruleset did I notice all the rules for that port were TCP only despite the service being UDP. Manually adding the correct UDP rules with nft fixed it immediately.

Workaround for anyone hitting this — manually add the rules on the routing peer:

sudo nft add rule ip netbird netbird-rt-fwd ip saddr <proxy-vpn-ip> ip daddr <destination-subnet> udp dport <port> counter accept

Note these rules are wiped on netbird restart so it's not a permanent fix.

  • Checked for newer NetBird versions
  • Searched for similar issues on GitHub (including closed ones)
  • Restarted the NetBird client
  • Checked firewall settings
Originally created by @SamFusco on GitHub (Mar 30, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5734 **Describe the problem** When exposing a service through the NetBird reverse proxy using UDP (e.g. `udp://192.168.1.2:56789`), the routing peer generates nftables forwarding rules using `tcp dport` instead of `udp dport`. This means UDP packets arriving on the routing peer via the WireGuard tunnel (`wt0`) are silently dropped and never forwarded to the destination. **To Reproduce** 1. Create a service in Networks → Services pointing to a UDP destination e.g. `udp://192.168.1.2:56789` 2. On the routing peer, run `sudo nft list ruleset | grep 56789` 3. Notice the generated rule uses `tcp dport 56789` despite the service being configured as UDP **Expected behavior** The generated nftables rule in the `netbird-rt-fwd` chain should use `udp dport` when the service is configured with a `udp://` destination. Instead it always generates `tcp dport` regardless of the protocol specified. **Are you using NetBird Cloud?** Self-hosted **NetBird version** 0.67.1 **Is any other VPN software installed?** No **Debug output** `sudo nft list ruleset | grep -A2 "56789"` Output showing `tcp dport` instead of `udp dport`. And the tcpdump showing packets arriving on `wt0` but never leaving on `enp6s18`: ``` 23:15:32.874718 wt0 In IP 100.94.56.138.35335 > 192.168.1.2.56789: UDP, length 148 23:15:37.945205 wt0 In IP 100.94.56.138.35335 > 192.168.1.2.56789: UDP, length 148 ``` UDP relay added in the Proxy ``` 2026-03-30T12:31:08.243Z INFO [listen_port: 443, service_id: d756q37dqmns73fnnl2g, target: 192.168.1.2:56789] proxy/server.go:1401: UDP relay added ``` nftable rule generated ``` ip saddr 100.94.56.138 ip daddr 192.168.1.0/24 tcp dport 56789-56789 counter packets 0 bytes 0 accept ip saddr 100.94.175.191 ip daddr 192.168.1.0/24 tcp dport 56789-56789 counter packets 0 bytes 0 accept ip saddr 100.94.116.185 ip daddr 192.168.1.0/24 tcp dport 56789-56789 counter packets 0 bytes 0 accept ``` **Screenshots** Just the GUI udp service **Additional context** Took a while to track this one down. Traffic was making it through Netbird-proxy → WireGuard tunnel fine, but dying on the routing peer. tcpdump on `wt0` showed packets arriving, but nothing ever appeared on the physical interface. Only after inspecting the nftables ruleset did I notice all the rules for that port were TCP only despite the service being UDP. Manually adding the correct UDP rules with `nft` fixed it immediately. Workaround for anyone hitting this — manually add the rules on the routing peer: ```bash sudo nft add rule ip netbird netbird-rt-fwd ip saddr <proxy-vpn-ip> ip daddr <destination-subnet> udp dport <port> counter accept ``` Note these rules are wiped on netbird restart so it's not a permanent fix. - [x] Checked for newer NetBird versions - [x] Searched for similar issues on GitHub (including closed ones) - [x] Restarted the NetBird client - [x] Checked firewall settings
saavagebueno added the triage-needed label 2026-08-05 01:30:33 -04:00
Author
Owner

@lixmal commented on GitHub (Apr 7, 2026):

There was indeed a bug like that, but it has been already fixed in netbird management v0.67.0+. It's impossible to debug without any debug info, which you omitted.

<!-- gh-comment-id:4196544374 --> @lixmal commented on GitHub (Apr 7, 2026): There was indeed a bug like that, but it has been already fixed in netbird management v0.67.0+. It's impossible to debug without any debug info, which you omitted.
Sign in to join this conversation.
No Label triage-needed
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#11701