XDNS: Additional A queries by the recursive DNS resolver alter the TXT client’s method and break the transport
Author: Katze-942Created Aug 27, 2026Updated Aug 27, 2026
### Integrity requirements
- [x] I have read all the comments in the issue template and ensured that this issue meet the requirements.
- [x] I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values.
- [x] I provided the complete config and logs, rather than just providing the truncated parts based on my own judgment.
- [x] I searched issues and did not find any similar issues.
- [x] The problem can be successfully reproduced in the latest Release
### Description
The XDNS client is explicitly configured to use TXT:
```json
"resolvers": [
"t.example:txt+udp://127.0.0.1:15354"
]
```
Some recursive DNS servers independently send additional A queries for the same QNAME to the authoritative server while processing a TXT query. For example, AdGuard sends TXT, then A, and then TXT again. XDNS treats all three queries as genuine XDNS queries and apparently cannot return responses to the A queries because of the high MTU.
When XDNS cannot return responses to the A queries (this is my assumption), they begin to accumulate in memory and Xray-core's memory usage grows by gigabytes. In my case, approximately 5,000 A queries arrived in total, and RAM usage increased significantly as a result.
The current server-side workaround is:
```json
"domains": ["t.example:txt"]
```
This rejects A queries, after which at least the memory leak stops.
### Reproduction Method
I prepared a Python script that pretends to be a DNS resolver.
1. Download the latest Xray-core pre-release (at the time of writing this issue, it is 26.7.28).
2. Download `client.json` and `server.json` to the same machine and start two Xray-core instances.
3. Start `resolver.py`:
```python
#!/usr/bin/env python3
import concurrent.futures
import socket
import struct
import threading
import time
LISTEN = ("127.0.0.1", 15354)
XRAY = ("127.0.0.1", 15353)
WORKERS = 256
def type_offset(packet):
offset = 12
while packet[offset]:
offset += packet[offset] + 1
return offset + 1
def qtype(packet):
offset = type_offset(packet)
return struct.unpack("!H", packet[offset : offset + 2])[0]
def with_type(packet, value):
offset = type_offset(packet)
return packet[:offset] + struct.pack("!H", value) + packet[offset + 2 :]
def replay(query, client):
upstream = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
upstream.settimeout(2)
try:
upstream.sendto(query, XRAY) # Original TXT.
time.sleep(0.120)
upstream.sendto(with_type(query, 1), XRAY) # Auxiliary A.
time.sleep(0.078)
upstream.sendto(query, XRAY) # Repeated TXT.
for _ in range(3):
response, _ = upstream.recvfrom(65535)
if qtype(response) == 16:
listener.sendto(response, client)
break
except TimeoutError:
print("upstream timeout", flush=True)
finally:
upstream.close()
slots.release()
listener = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
listener.bind(LISTEN)
slots = threading.BoundedSemaphore(WORKERS)
pool = concurrent.futures.ThreadPoolExecutor(max_workers=WORKERS)
print(f"listening on {LISTEN[0]}:{LISTEN[1]} ({WORKERS} workers)", flush=True)
count = 0
while True:
query, client = listener.recvfrom(65535)
if qtype(query) != 16: # The Xray client must ask for TXT.
continue
count += 1
if not slots.acquire(blocking=False):
print(f"{count}: worker pool full", flush=True)
continue
print(f"{count}: client=TXT, server=TXT -> A -> TXT", flush=True)
pool.submit(replay, query, client)
```
4. Run curl:
```shell
curl --socks5 "127.0.0.1:11080" https://ifconfig.co/
```
### Client config
{
"log": {
"loglevel": "debug",
"dnsLog": true
},
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 11080,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "xdns-out",
"protocol": "vless",
"settings": {
"address": "127.0.0.1",
"port": 15353,
"id": "11111111-1111-4111-8111-111111111111",
"encryption": "none"
},
"streamSettings": {
"method": "mkcp",
"security": "none",
"kcpSettings": {
"mtu": 130,
"tti": 50,
"uplinkCapacity": 5,
"downlinkCapacity": 10,
"congestion": true,
"readBufferSize": 2,
"writeBufferSize": 2
},
"finalmask": {
"udp": [
{
"type": "xdns",
"settings": {
"resolvers": [
"t.example:txt+udp://127.0.0.1:15354"
]
}
}
]
}
}
}
]
}
### Server config
{
"log": {
"loglevel": "debug",
"dnsLog": true
},
"inbounds": [
{
"tag": "xdns-in",
"listen": "127.0.0.1",
"port": 15353,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "11111111-1111-4111-8111-111111111111"
}
],
"decryption": "none"
},
"streamSettings": {
"method": "mkcp",
"security": "none",
"kcpSettings": {
"mtu": 900,
"tti": 50,
"uplinkCapacity": 10,
"downlinkCapacity": 20,
"congestion": true,
"readBufferSize": 2,
"writeBufferSize": 2
},
"finalmask": {
"udp": [
{
"type": "xdns",
"settings": {
"domains": [
"t.example"
]
}
}
]
}
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct"
}
]
}
### Client log
Xray 26.7.28 (Xray, Penetrates Everything.) 5ca6f4b (go1.26.5 linux/amd64)
A unified platform for anti-censorship.
2026/08/27 17:48:50.922520 [Info] infra/conf/serial: Reading config: &{Name:client.json Format:json}
2026/08/27 17:48:50.923385 [Debug] app/log: Logger started
2026/08/27 17:48:50.923407 [Debug] app/proxyman/inbound: creating stream worker on 127.0.0.1:11080
2026/08/27 17:48:50.923607 [Info] transport/internet/tcp: listening TCP on 127.0.0.1:11080
2026/08/27 17:48:50.923843 [Warning] core: Xray 26.7.28 started
2026/08/27 17:49:06.983999 [Info] [2356556535] proxy/socks: TCP Connect request to tcp:188.40.167.81:443
2026/08/27 17:49:06.984019 [Info] [2356556535] app/dispatcher: default route for tcp:188.40.167.81:443
2026/08/27 17:49:06.984024 [Info] [2356556535] transport/internet/kcp: dialing mKCP to udp:127.0.0.1:15353
2026/08/27 17:49:06.984026 [Debug] [2356556535] transport/internet: dialing to udp:127.0.0.1:15353
2026/08/27 17:49:06.984043 from tcp:127.0.0.1:55380 accepted tcp:188.40.167.81:443 [socks-in >> xdns-out]
2026/08/27 17:49:06.984051 [Info] transport/internet/kcp: #6536 creating connection to 127.0.0.1:15353
2026/08/27 17:49:06.984054 [Info] [2356556535] proxy/vless/outbound: tunneling request to tcp:188.40.167.81:443 via 127.0.0.1:15353
2026/08/27 17:49:10.780462 [Debug] transport/internet/kcp: #6536 entering state 1 at 3796
2026/08/27 17:49:10.780483 [Info] transport/internet/kcp: #6536 closing connection to 127.0.0.1:15353
2026/08/27 17:49:11.985233 [Debug] transport/internet/kcp: #6536 entering state 3 at 5001
2026/08/27 17:49:11.985245 [Debug] transport/internet/kcp: #6536 sending terminating cmd.
2026/08/27 17:49:12.184062 [Debug] transport/internet/kcp: #6536 entering state 5 at 5199
2026/08/27 17:49:12.184085 [Info] transport/internet/kcp: #6536 terminating connection to 127.0.0.1:15353
2026/08/27 17:49:12.184098 [Debug] transport/internet/finalmask/xdns: xdns closed
### Server log
Xray 26.7.28 (Xray, Penetrates Everything.) 5ca6f4b (go1.26.5 linux/amd64)
A unified platform for anti-censorship.
2026/08/27 17:49:03.076715 [Info] infra/conf/serial: Reading config: &{Name:server.json Format:json}
2026/08/27 17:49:03.077746 [Debug] app/log: Logger started
2026/08/27 17:49:03.077862 [Debug] app/proxyman/inbound: creating stream worker on 127.0.0.1:15353
2026/08/27 17:49:03.077995 [Info] transport/internet/udp: listening UDP on 127.0.0.1:15353
2026/08/27 17:49:03.078025 [Info] transport/internet/kcp: listening on 127.0.0.1:15353
2026/08/27 17:49:03.078032 [Warning] core: Xray 26.7.28 started
2026/08/27 17:49:06.985272 [Info] transport/internet/kcp: #6536 creating connection to [fd00::2cb2:f1a1:1cbc:f75d]:0
2026/08/27 17:49:06.985287 [Info] [2454875892] proxy/vless/inbound: firstLen = 112
2026/08/27 17:49:06.985295 [Info] [2454875892] proxy/vless/inbound: received request for tcp:188.40.167.81:443
2026/08/27 17:49:06.985299 [Info] [2454875892] app/dispatcher: default route for tcp:188.40.167.81:443
2026/08/27 17:49:06.985372 [Info] [2454875892] transport/internet/tcp: dialing TCP to tcp:188.40.167.81:443
2026/08/27 17:49:06.985391 [Debug] [2454875892] transport/internet: dialing to tcp:188.40.167.81:443
2026/08/27 17:49:06.985390 from [fd00::2cb2:f1a1:1cbc:f75d]:0 accepted tcp:188.40.167.81:443 [xdns-in >> direct]
2026/08/27 17:49:06.985642 [Info] [2454875892] proxy/freedom: connection opened to tcp:188.40.167.81:443, local endpoint 172.18.0.1:45014, remote endpoint 188.40.167.81:443
2026/08/27 17:49:06.985653 [Debug] [2454875892] proxy: CopyRawConn (maybe) readv
2026/08/27 17:49:07.235368 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 900+2 > 118
2026/08/27 17:49:07.235389 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 551+2 > 118
2026/08/27 17:49:07.235391 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 900+2 > 118
2026/08/27 17:49:07.235393 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 900+2 > 118
2026/08/27 17:49:07.235394 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 684+2 > 118
2026/08/27 17:49:07.335845 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 900+2 > 118
2026/08/27 17:49:07.335865 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 551+2 > 118
2026/08/27 17:49:07.335869 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 900+2 > 118
2026/08/27 17:49:07.335872 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 900+2 > 118
2026/08/27 17:49:07.335874 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 684+2 > 118
2026/08/27 17:49:07.435782 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 900+2 > 118
2026/08/27 17:49:07.435820 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 551+2 > 118
2026/08/27 17:49:07.435841 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 900+2 > 118
2026/08/27 17:49:07.435845 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 900+2 > 118
2026/08/27 17:49:07.435848 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 684+2 > 118
2026/08/27 17:49:07.636194 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 900+2 > 118
2026/08/27 17:49:07.636217 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 551+2 > 118
2026/08/27 17:49:07.636221 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 900+2 > 118
2026/08/27 17:49:07.636223 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 900+2 > 118
2026/08/27 17:49:07.636225 [Debug] transport/internet/finalmask/xdns: [fd00::2cb2:f1a1:1cbc:f75d]:0 mask write err short write 684+2 > 118
2026/08/27 17:49:07.801570 [Debug] transport/internet/finalmask/xdns: 127.0.0.1:35066 [fd00::2cb2:f1a1:1cbc:f75d]:0 xdns payload too large for rrtype 1 900
2026/08/27 17:49:07.801585 [Debug] transport/internet/finalmask/xdns: 127.0.0.1:35066 [fd00::2cb2:f1a1:1cbc:f75d]:0 xdns payload too large for rrtype 1 900
2026/08/27 17:49:07.801588 [Debug] transport/internet/finalmask/xdns: 127.0.0.1:35066 [fd00::2cb2:f1a1:1cbc:f75d]:0 xdns payload too large for rrtype 1 684
2026/08/27 17:49:07.801592 [Debug] transport/internet/finalmask/xdns: 127.0.0.1:35066 [fd00::2cb2:f1a1:1cbc:f75d]:0 xdns payload too large for rrtype 1 33
2026/08/27 17:49:07.801594 [Debug] transport/internet/finalmask/xdns: 127.0.0.1:35066 [fd00::2cb2:f1a1:1cbc:f75d]:0 xdns payload too large for rrtype 1 33
2026/08/27 17:49:07.801596 [Debug] transport/internet/finalmask/xdns: 127.0.0.1:35066 [fd00::2cb2:f1a1:1cbc:f75d]:0 xdns payload too large for rrtype 1 33
2026/08/27 17:49:07.801597 [Debug] transport/internet/finalmask/xdns: 127.0.0.1:35066 [fd00::2cb2:f1a1:1cbc:f75d]:0 xdns payload too large for rrtype 1 900
2026/08/27 17:49:07.801599 [Debug] transport/internet/finalmask/xdns: 127.0.0.1:35066 [fd00::2cb2:f1a1:1cbc:f75d]:0 xdns payload too large for rrtype 1 551
2026/08/27 17:49:07.801601 [Debug] transport/internet/finalmask/xdns: 127.0.0.1:35066 [fd00::2cb2:f1a1:1cbc:f75d]:0 xdns payload too large for rrtype 1 900
2026/08/27 17:49:07.801603 [Debug] transport/internet/finalmask/xdns: 127.0.0.1:35066 [fd00::2cb2:f1a1:1cbc:f75d]:0 xdns payload too large for rrtype 1 900
2026/08/27 17:49:07.801605 [Debug] transport/internet/finalmask/xdns: 127.0.0.1:35066 [fd00::2cb2:f1a1:1cbc:f75d]:0 xdns payload too large for rrtype 1 684
2026/08/27 17:49:08.000367 [Debug] transport/internet/finalmask/xdns: 127.0.0.1:34643 [fd00::2cb2:f1a1:1cbc:f75d]:0 xdns payload too large for rrtype 1 684
2026/08/27 17:49:11.932167 [Debug] transport/internet/kcp: #6536 entering state 1 at 4947
2026/08/27 17:49:11.932219 [Info] transport/internet/kcp: #6536 closing connection to [fd00::2cb2:f1a1:1cbc:f75d]:0
2026/08/27 17:49:11.936296 [Debug] transport/internet/kcp: #6536 entering state 3 at 4951
2026/08/27 17:49:11.936313 [Debug] transport/internet/kcp: #6536 sending terminating cmd.
2026/08/27 17:49:11.985511 [Debug] transport/internet/kcp: #6536 sending terminating cmd.
2026/08/27 17:49:11.985587 [Debug] transport/internet/kcp: #6536 entering state 5 at 5000
2026/08/27 17:49:11.985598 [Info] transport/internet/kcp: #6536 terminating connection to [fd00::2cb2:f1a1:1cbc:f75d]:0
Source: XTLS/Xray-core