Skip to content

HTTP/3 UDP socket leak leads to local port exhaustion after 0-RTT rejected #511

Description

@notr1ch

I am running dnsproxy on Linux AMD64 as follows:

2026/07/17 15:38:38.355881 INFO dnsproxy starting version=v0.83.0 revision=d020fcc62cfd62958706295d7c9d9e82ae015f52 branch=v0.83.0 commit_time=1783069482

dnsproxy -l 127.0.0.6 -u h3://dns.google/dns-query -b 8.8.8.8:53

This setup has been working well for many months, however today I began to get 0-RTT rejected responses from Google DNS:

Jul 17 15:36:14 dnsproxy[436873]: 2026/07/17 15:36:14.221298 ERROR exchange failed prefix=dnsproxy upstream=https://dns.google:443/dns-query question=";accounts.google.com.\tIN\t A" duration=26.777927ms err="exchanging: requesting https://dns.google:443/dns-query: Get_0rtt \"https://dns.google:443/dns-query?dns=AAABEAABAAAAAAABCGFjY291bnRzBmdvb2dsZQNjb20AAAEAAQAAKQTQAACAAAAA\": http3: parsing frame failed: 0-RTT rejected"
Jul 17 15:36:14 dnsproxy[436873]: 2026/07/17 15:36:14.227267 ERROR exchange failed prefix=dnsproxy upstream=https://dns.google:443/dns-query question=";history.l.google.com.\tIN\t HTTPS" duration=12.137872ms err="exchanging: requesting https://dns.google:443/dns-query: Get_0rtt \"https://dns.google:443/dns-query?dns=AAABEAABAAAAAAABB2hpc3RvcnkBbAZnb29nbGUDY29tAABBAAEAACkE0AAAgAAAAA\": http3: parsing frame failed: 0-RTT rejected"
Jul 17 15:36:14 dnsproxy[436873]: 2026/07/17 15:36:14.423144 ERROR exchange failed prefix=dnsproxy upstream=https://dns.google:443/dns-query question=";2-prod-dynamite-prod-02-us-signaler-pa.clients6.google.com.\tIN\t HTTPS" duration=16.508161ms err="exchanging: requesting https://dns.google:443/dns-query: Get_0rtt \"https://dns.google:443/dns-query?dns=AAABEAABAAAAAAABJjItcHJvZC1keW5hbWl0ZS1wcm9kLTAyLXVzLXNpZ25hbGVyLXBhCGNsaWVudHM2Bmdvb2dsZQNjb20AAEEAAQAAKQTQAACAAAAA\": http3: parsing frame failed: 0-RTT rejected"
Jul 17 15:36:15 dnsproxy[436873]: 2026/07/17 15:36:15.542314 ERROR exchange failed prefix=dnsproxy upstream=https://dns.google:443/dns-query question=";mail.google.com.\tIN\t A" duration=28.740321ms err="exchanging: requesting https://dns.google:443/dns-query: Get_0rtt \"https://dns.google:443/dns-query?dns=AAABEAABAAAAAAABBG1haWwGZ29vZ2xlA2NvbQAAAQABAAApBNAAAIAAAAA\": http3: parsing frame failed: 0-RTT rejected"
Jul 17 15:36:15 dnsproxy[436873]: 2026/07/17 15:36:15.542355 ERROR exchange failed prefix=dnsproxy upstream=https://dns.google:443/dns-query question=";mail.google.com.\tIN\t HTTPS" duration=28.834902ms err="exchanging: requesting https://dns.google:443/dns-query: Get_0rtt \"https://dns.google:443/dns-query?dns=AAABEAABAAAAAAABBG1haWwGZ29vZ2xlA2NvbQAAQQABAAApBNAAAIAAAAA\": http3: parsing frame failed: 0-RTT rejected"

After such responses, dnsproxy seems to open / leak a number of new UDP sockets:

# lsof -p 436873
COMMAND     PID            USER  FD      TYPE             DEVICE SIZE/OFF      NODE NAME
dnsproxy 436873 dnsproxy-google cwd       DIR              254,1     4096         2 /
dnsproxy 436873 dnsproxy-google rtd       DIR              254,1     4096         2 /
dnsproxy 436873 dnsproxy-google txt       REG              254,1 11935906   8782474 /opt/dnsproxy/dnsproxy
dnsproxy 436873 dnsproxy-google   0r      CHR                1,3      0t0         4 /dev/null
dnsproxy 436873 dnsproxy-google   1u     unix 0x000000007c9226f4      0t0 365483103 type=STREAM (CONNECTED)
dnsproxy 436873 dnsproxy-google   2u     unix 0x000000007c9226f4      0t0 365483103 type=STREAM (CONNECTED)
dnsproxy 436873 dnsproxy-google   3r      REG               0,27        0    293214 /sys/fs/cgroup/system.slice/dnsproxy-google.service/cpu.max
dnsproxy 436873 dnsproxy-google   4u  a_inode               0,16        0        58 [eventpoll:5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]
dnsproxy 436873 dnsproxy-google   5u  a_inode               0,16        0        58 [eventfd:5]
dnsproxy 436873 dnsproxy-google   6u     IPv4          365616831      0t0       UDP 127.0.0.6:domain
dnsproxy 436873 dnsproxy-google   7u     IPv4          365616836      0t0       TCP 127.0.0.6:domain (LISTEN)
dnsproxy 436873 dnsproxy-google   8u     IPv6          365979239      0t0       UDP *:42047
dnsproxy 436873 dnsproxy-google   9u     IPv6          366019813      0t0       UDP *:52678
dnsproxy 436873 dnsproxy-google  10u     IPv6          365946353      0t0       UDP *:34188
dnsproxy 436873 dnsproxy-google  11u     IPv6          365983107      0t0       UDP *:39381
dnsproxy 436873 dnsproxy-google  12u     IPv6          366008373      0t0       UDP *:57130
dnsproxy 436873 dnsproxy-google  13u     IPv6          366014604      0t0       UDP *:37532
dnsproxy 436873 dnsproxy-google  14u     IPv6          366011470      0t0       UDP *:49196
dnsproxy 436873 dnsproxy-google  15u     IPv6          366021273      0t0       UDP *:58625
dnsproxy 436873 dnsproxy-google  16u     IPv6          366025846      0t0       UDP *:34846
dnsproxy 436873 dnsproxy-google  17u     IPv6          366000931      0t0       UDP *:56331
dnsproxy 436873 dnsproxy-google  18u     IPv6          365892103      0t0       UDP *:46402
dnsproxy 436873 dnsproxy-google  19u     IPv6          366021275      0t0       UDP *:56870
dnsproxy 436873 dnsproxy-google  20u     IPv6          365892105      0t0       UDP *:49549
dnsproxy 436873 dnsproxy-google  21u     IPv6          365908932      0t0       UDP *:56892

Eventually, as further 0-RTT rejected errors accumulate, all local ports are exhausted and DNS resolution begins to fail:

Jul 17 14:31:06 dnsproxy[423785]: 2026/07/17 14:31:06.739988 ERROR exchange failed prefix=dnsproxy upstream=https://dns.google:443/dns-query question=";5-prod-dynamite-prod-07-us-signaler-pa.clients6.google.com.\tIN\t A" duration=9.433834ms err="requesting https://dns.google:443/dns-query: Get_0rtt \"https://dns.google:443/dns-query?dns=AAABEAABAAAAAAABJjUtcHJvZC1keW5hbWl0ZS1wcm9kLTA3LXVzLXNpZ25hbGVyLXBhCGNsaWVudHM2Bmdvb2dsZQNjb20AAAEAAQAAKQTQAACAAAAA\": listen udp 0.0.0.0:0: bind: address already in use"
Jul 17 14:31:06 dnsproxy[423785]: 2026/07/17 14:31:06.740656 ERROR exchange failed prefix=dnsproxy upstream=https://dns.google:443/dns-query question=";5-prod-dynamite-prod-07-us-signaler-pa.clients6.google.com.\tIN\t HTTPS" duration=10.310516ms err="requesting https://dns.google:443/dns-query: Get_0rtt \"https://dns.google:443/dns-query?dns=AAABEAABAAAAAAABJjUtcHJvZC1keW5hbWl0ZS1wcm9kLTA3LXVzLXNpZ25hbGVyLXBhCGNsaWVudHM2Bmdvb2dsZQNjb20AAEEAAQAAKQTQAACAAAAA\": listen udp 0.0.0.0:0: bind: address already in use"
Jul 17 14:31:07 dnsproxy[423785]: 2026/07/17 14:31:07.267416 ERROR exchange failed prefix=dnsproxy upstream=https://dns.google:443/dns-query question=";storage.googleapis.com.\tIN\t A" duration=10.787386ms err="requesting https://dns.google:443/dns-query: Get_0rtt \"https://dns.google:443/dns-query?dns=AAABEAABAAAAAAABB3N0b3JhZ2UKZ29vZ2xlYXBpcwNjb20AAAEAAQAAKQTQAACAAAAA\": listen udp 0.0.0.0:0: bind: address already in use"
Jul 17 14:31:07 dnsproxy[423785]: 2026/07/17 14:31:07.324147 ERROR exchange failed prefix=dnsproxy upstream=https://dns.google:443/dns-query question=";prod-dynamite-prod-04-us-signaler-pa.clients6.google.com.\tIN\t HTTPS" duration=10.892828ms err="requesting https://dns.google:443/dns-query: Get_0rtt \"https://dns.google:443/dns-query?dns=AAABEAABAAAAAAABJHByb2QtZHluYW1pdGUtcHJvZC0wNC11cy1zaWduYWxlci1wYQhjbGllbnRzNgZnb29nbGUDY29tAABBAAEAACkE0AAAgAAAAA\": listen udp 0.0.0.0:0: bind: address already in use"
Jul 17 14:31:07 dnsproxy[423785]: 2026/07/17 14:31:07.325076 ERROR exchange failed prefix=dnsproxy upstream=https://dns.google:443/dns-query question=";prod-dynamite-prod-04-us-signaler-pa.clients6.google.com.\tIN\t A" duration=11.908636ms err="requesting https://dns.google:443/dns-query: Get_0rtt \"https://dns.google:443/dns-query?dns=AAABEAABAAAAAAABJHByb2QtZHluYW1pdGUtcHJvZC0wNC11cy1zaWduYWxlci1wYQhjbGllbnRzNgZnb29nbGUDY29tAAABAAEAACkE0AAAgAAAAA\": listen udp 0.0.0.0:0: bind: address already in use"
Jul 17 14:31:07 dnsproxy[423785]: 2026/07/17 14:31:07.359561 ERROR exchange failed prefix=dnsproxy upstream=https://dns.google:443/dns-query question=";prod-dynamite-prod-04-us-signaler-pa.clients6.google.com.\tIN\t A" duration=11.576853ms err="requesting https://dns.google:443/dns-query: Get_0rtt \"https://dns.google:443/dns-query?dns=AAABEAABAAAAAAABJHByb2QtZHluYW1pdGUtcHJvZC0wNC11cy1zaWduYWxlci1wYQhjbGllbnRzNgZnb29nbGUDY29tAAABAAEAACkE0AAAgAAAAA\": listen udp 0.0.0.0:0: bind: address already in use"
Jul 17 14:31:07 dnsproxy[423785]: 2026/07/17 14:31:07.376394 ERROR exchange failed prefix=dnsproxy upstream=https://dns.google:443/dns-query question=";ie_sla0.apple-dns.net.\tIN\t A" duration=11.355851ms err="requesting https://dns.google:443/dns-query: Get_0rtt \"https://dns.google:443/dns-query?dns=AAABEAABAAAAAAABB2llX3NsYTAJYXBwbGUtZG5zA25ldAAAAQABAAApBNAAAIAAAAA\": listen udp 0.0.0.0:0: bind: address already in use"
Jul 17 14:31:07 dnsproxy[423785]: 2026/07/17 14:31:07.377400 ERROR exchange failed prefix=dnsproxy upstream=https://dns.google:443/dns-query question=";prod-dynamite-prod-04-us-signaler-pa.clients6.google.com.\tIN\t A" duration=7.240127ms err="requesting https://dns.google:443/dns-query: Get_0rtt \"https://dns.google:443/dns-query?dns=AAABEAABAAAAAAABJHByb2QtZHluYW1pdGUtcHJvZC0wNC11cy1zaWduYWxlci1wYQhjbGllbnRzNgZnb29nbGUDY29tAAABAAEAACkE0AAAgAAAAA\": listen udp 0.0.0.0:0: bind: address already in use"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions