The iPad was on Tailscale: a WebRTC debugging story
TL;DR Highlight
iPad-only blank page came from a webrtc-rs MTU constant plus Tailscale dropping IPv6 fragments
Who Should Read
Backend or web developer whose WebRTC data channel or UDP-based P2P feature hangs only on certain devices
Core Mechanics
- Only the iPad hung on the first GET
- The data channel was open and the box agent believed it had sent the response.
- The browser received only the 220-byte header, never the body.
- The packets never arrived, so not WebKit
- getStats() showed the iPad's candidate pair frozen at 2,144 bytes over 18 packets.
- Retransmissions continued but the transport counter never moved.
- webrtc-rs hardcodes INITIAL_MTU at 1228
- It is not configurable or updated, and with encryption it becomes 1,265 bytes on the wire.
- Adding IP/UDP headers gives 1,293 bytes on IPv4 or 1,313 on IPv6, above Tailscale's 1,280 tunnel limit.
- Tailscale drops IPv6 fragments
- Its parser classifies packets with an IPv6 Fragment header as unknown protocol, so default deny fires.
- The tailscaled_inbound_dropped_packets_total{reason="acl"} counter increased.
- Two ping commands reproduce it without WebRTC
- ping -s 1400 over IPv6 gave 100% loss while IPv4 worked.
- Every Tailscale device tested showed the same loss.
- 800-byte cap worked but 1,200 failed
- 800 bytes never fragments, so nothing gets dropped.
- webrtc-rs pads its first packet to 1,228, pushing 1,200-byte messages over the limit.
Community Reactions
- Opinion that MTU black holes are the worst
- Every health check is small enough to survive.
- Opinion that dropping UDP fragments in Tailscale is baffling
- The commenter guessed the ACL module rejects them because fragments lack port numbers.
- They suggested a global fragments on/off setting or blocking only the first fragment that carries the port.
- Experience of a similar bug on the iOS simulator
- HTTP3/QUIC sent 1506-byte UDP packets and broke authentication.
- They worked around it by denying UDP ports 80/443 in the firewall.
- Info that the author opened a fix PR for webrtc-rs (#807)
- The Tailscale side is filed as issue #20083.
How to Apply
- Test the path with large pings
- When one device hangs, run ping -s 100 and ping -s 1400 against its IPv4 and IPv6 addresses today.
- If only 1400 loses packets, treat it as a fragment problem and isolate the path before touching WebRTC code.
- Cap data channel messages at 800 bytes
- Lower the sender's max chunk size to 800 bytes when using webrtc-rs.
- Do not use 1,200 because first-packet padding still exceeds the limit.
- Debug from the receiver side
- Do not trust sender-side tcpdump alone; log getStats() byte counts on the receiver too.
- If retransmits continue while received bytes stay frozen, suspect the network.
- Ask what path only that device takes
- Compare the failing and working devices for VPN, IPv6 and ICE candidate pair differences.
- Log the selected candidate pair.
Try It
# Paste in a shell: check IPv6 fragment loss on a Tailscale device (the article's 2-command repro)
TS6={{peer's Tailscale IPv6 address}}
ping -c 3 -s 100 $TS6
ping -c 3 -s 1400 $TS6
# If only the second shows 100% loss, IPv6 fragments are being dropped
tailscale metrics print | grep dropped_packetsTerminology
Related Papers
LLMs are making formal software verification feasible at a much larger scale
Claude proved no-crash properties for 123 open-source libraries and found bugs along the way.
PHP2Shell: AI uncovers critical RCE in PHP
Wiz used AI to turn a decade-old PHP core flaw into a working RCE exploit
Using LLM for confidence scoring is a bad idea
An LLM's self-reported confidence is plausible text, not a measurement; build scores from outside rules.
The Judge Can Debias Itself: Awareness and Self-Debiasing for Reliable LLM-as-a-Judge
Warning an LLM judge about bias or letting it self-critique improved 20 of 21 model–bias combinations.
90% of US working hours are spent on tasks not covered well by AI benchmarks
Mapping 29 benchmarks to job tasks shows 90% of US working hours lack good coverage
Postgres 19 delayed after AI reviewers find more bugs than humans can fix
LLM code review surfaced so many bugs that Postgres 19 slipped to November and 8-10 features were reverted
Show HN: Gemini 4 Argon plays StarCraft
LLMs wrote StarCraft bots in one hour; GPT-6 Astra scored highest.
A Plausible Explanation Is Enough to Mislead Multimodal Judges
Adding plausible explanations to fixed answers cut MLLM judges' wrong-answer rejection by 12.7–13.8 points.