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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions