Skip to content

CONNECT-IP: a path MTU drop during an HTTP/3 tunnel black-holes packets instead of signalling or ending the tunnel #1237

Closed

Description

@privateip

What happens

docs/edge/masque-service.md (Packet size) says that over HTTP/3 a gVPC packet larger than the current QUIC datagram size gets an ICMPv6 Packet Too Big, and that when the path shrinks so a 1280-byte packet no longer fits, the request ends and the packet is counted as reason="path_mtu".

When the path MTU drops during an open HTTP/3 tunnel, neither happens. The server keeps the QUIC packet size it had already discovered, so connect-ip-go never finds a packet too large for a datagram. Oversized packets are dropped on the path without any ICMPv6 error, and once the path can no longer carry 1280-byte inner packets the tunnel stays open but carries none of them. Nothing is counted: galactic_connectip_packets_denied_total{reason="path_mtu"} and galactic_connectip_tunnel_ends_total{cause="path_mtu"} stay at zero.

The likely cause is in the transport, not the packet policy. quic-go v0.63.0 only grows its packet size through path MTU discovery and never shrinks it on loss, and on Linux it sets IPV6_PMTUDISC_PROBE, so the kernel ignores any Packet Too Big the socket receives. The server's DatagramTooLargeError check, which builds the Packet Too Big and drives the path_mtu ending, therefore never fires for a path that shrank after the handshake.

How it was seen

In the containerlab gVPC lab, with the MASQUE service from config/masque, a client sent 1280-byte ICMPv6 echo requests through an HTTP/3 tunnel to a workload every 100 ms. The workload also pinged the client's address with 1280-byte and 1400-byte packets. The MTU of the provider pod's host-side veth was then lowered every 9 s:

Host-side veth MTU 1280-byte packets, both ways 1400-byte packets toward the client ICMPv6 Packet Too Big at the workload Tunnel
1500 delivered delivered none open
1400 to 1360 delivered dropped none open
1340 to 1300 dropped dropped none open
1500 again delivered delivered none resumed

The provider's metrics showed no path_mtu drop or tunnel end; the only tunnel end counted was the client's own close.

Expected

As documented: above the 1280-byte floor, an oversized gVPC packet draws an ICMPv6 Packet Too Big to its sender; below it, the tunnel ends and the drop is counted as path_mtu, so the connector reconnects and the 1280-byte admission probe decides whether the path still works.

Related

#982 (lab rows for live path MTU changes). The MASQUE service lab suite's mtu-live-drop row reproduces this and fails until it is fixed.

Activity

  1. added theissue type on Oct 29, 2026
  2. privateip commented on Oct 29, 2026

    @privateip
    CollaboratorAuthor

    This issue now also tracks the live path-MTU criterion from #982, which closed without it: a path-MTU reduction during an active HTTP/3 tunnel must produce ICMPv6 Packet Too Big or end the tunnel. Close this once the mtu-live-drop row in the MASQUE service lab suite passes. Draft #1243 is one candidate fix and is paused until its approach is agreed.

  3. privateip commented on Oct 29, 2026

    @privateip
    CollaboratorAuthor

    Closing. The Packet Too Big half ships in #1248: the server now sends fixed-size QUIC packets, so a gVPC packet larger than the tunnel carries gets a Packet Too Big reporting 1280, on any path that still carries those packets. The other half is a path that shrinks below 1280 bytes mid-tunnel and black-holes it. That needs its own design and moved to #1247, which also takes the live path-MTU criterion handed here from #982.

  4. privateip commented on Oct 29, 2026

    @privateip
    CollaboratorAuthor

    Reopened so it closes when its fix merges. #1248 fixes the Packet Too Big half and closes this issue on merge. The below-1280 black hole is #1247.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions