CoreDNS is a DNS server that chains plugins. In versions prior to 1.14.3, the DNS-over-QUIC (DoQ) server can be driven into unbounded goroutine and memory growth by a remote client that opens many QUIC streams and sends only 1 byte per stream. When the worker pool is full, CoreDNS still spawns a goroutine per accepted stream to wait for a worker token. Additionally, active workers block indefinitely in io.ReadFull() with no per-stream read deadline, allowing an attacker to pin all workers by sending a single byte so the read blocks waiting for the second byte of the DoQ length prefix. This enables an unauthenticated remote attacker to cause memory exhaustion and OOM-kill. This issue has been fixed in version 1.14.3. No known workarounds exist.
CoreDNS is a DNS server that chains plugins. In versions prior to 1.14.3, the DNS-over-QUIC (DoQ) server can be driven into unbounded goroutine and memory growth by a remote client that opens many QUIC streams and sends only 1 byte per stream. When the worker pool is full, CoreDNS still spawns a goroutine per accepted stream to wait for a worker token. Additionally, active workers block indefinitely in io.ReadFull() with no per-stream read deadline, allowing an attacker to pin all workers by sending a single byte so the read blocks waiting for the second byte of the DoQ length prefix. This enables an unauthenticated remote attacker to cause memory exhaustion and OOM-kill. This issue has been fixed in version 1.14.3. No known workarounds exist.
CoreDNS is a DNS server that chains plugins. In versions prior to 1.14.3, the DNS-over-QUIC (DoQ) server can be driven into unbounded goroutine and memory growth by a remote client that opens many QUIC streams and sends only 1 byte per stream. When the worker pool is full, CoreDNS still spawns a goroutine per accepted stream to wait for a worker token. Additionally, active workers block indefinitely in io.ReadFull() with no per-stream read deadline, allowing an attacker to pin all workers by sending a single byte so the read blocks waiting for the second byte of the DoQ length prefix. This enables an unauthenticated remote attacker to cause memory exhaustion and OOM-kill. This issue has been fixed in version 1.14.3. No known workarounds exist.
### Summary
CoreDNS' DNS-over-QUIC (DoQ) server can be driven into large goroutine and memory growth by a remote client that opens many QUIC streams and stalls after sending only 1 byte. Even with a small configured quic { worker_pool_size ... }, CoreDNS still spawns a goroutine per accepted stream (workers + waiters) and active workers can block indefinitely in io.ReadFull() with no per-stream read deadline, enabling unauthenticated remote DoS via memory exhaustion/OOM-kill.
### Details
CoreDNS' DoQ server uses a global worker pool (streamProcessPool) to limit concurrent stream processing, but when the pool is full it still spawns a goroutine per accepted stream that waits to acquire a worker token: select { case s.streamProcessPool <- ...: go ...; default: go ... wait for token ... } (core/dnsserver/server_quic.go)
Additionally, the DoQ message framing reads are blocking io.ReadFull() calls with no per-stream read deadline: readDOQMessage() reads the 2-byte length prefix and message body via io.ReadFull() (core/dnsserver/server_quic.go)
This allows an attacker to pin all workers by sending 1 byte (so io.ReadFull() blocks waiting for the second byte of the DoQ length prefix), while also creating an unbounded backlog of goroutines waiting for a worker token.
Note: this appears to be a result of an incomplete fix/regression for CVE-2025-47950 (GHSA-cvx7-x8pj-x2gw).
### PoC
1. Adjust COREDNS_BIN in the PoC to point at right path (see the top-level const definitions for tunables as well)
2. Run python3 ./doq-dos-repro.py
3. Expected sample output:
*** Start CoreDNS ***
Corefile: /tmp/vh-f003-doq-mem-regression/Corefile
Log: /tmp/vh-f003-doq-mem-regression/coredns.log
*** Baseline sample (idle) ***
rss_kib=49380 go_goroutines=17
*** Build + run partial-stream flooder ***
go: downloading golang.org/x/net v0.43.0
go: downloading golang.org/x/crypto v0.41.0
go: downloading go.uber.org/mock v0.5.2
go: downloading github.com/stretchr/testify v1.11.1
go: downloading golang.org/x/sys v0.35.0
go: downloading github.com/pmezard/go-difflib v1.0.0
go: downloading github.com/davecgh/go-spew v1.1.1
go: downloading gopkg.in/yaml.v3 v3.0.1
*** Candidate sample (during attack) ***
rss_kib=137968 go_goroutines=15557
*** Flooder output ***
opened conns=60 streams_per_conn=256 total_streams=15360
*** Wrote results ***
/tmp/vh-f003-doq-mem-regression/results.json
*** OK ***
DoQ flood caused goroutine/RSS growth despite worker_pool_size.
### Impact
Unauthenticated remote DoS on an encrypted DNS transport via goroutine/RSS growth leading to OOM-kill/crash and service outage.
EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.
Original publisher date fields
datePublished: May 5, 2026, 7:06:17 PM
dateUpdated: May 6, 2026, 3:14:54 PM
3 related source bulletins · separate from aliases
msrc_CVE-2026-32934: CoreDNS DNS-over-QUIC unbounded goroutine growth leads to denial of service
CVE-2026-32934
WID-SEC-W-2026-1283: CoreDNS: Mehrere Schwachstellen ermöglichen
No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.
NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.
Source analysis status: Analyzed
Weakness classifications: CWE-770
Original publisher date fields
published: 2026-05-05T20:16:35.853
lastModified: 2026-07-25T11:10:00.100
1 source CPE criteria · context only
cpe:2.3:a:coredns.io:coredns:*:*:*:*:*:*:*:*
The original JSON retains the logical configuration operators, exclusions and version bounds.
No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.