Skip to content

[bug] DoT query can fail after idle stale pooled connections since 1.13.11 #4150

@HMBSbige

Description

@HMBSbige

Operating system

Linux

System version

Arch Linux, Linux 7.0.9-arch1-1.1 x86_64

Installation type

Original sing-box Command Line

If you are using a graphical client, please provide the version of the client.

No response

Version

sing-box version 1.13.11

Environment: go1.25.9 linux/amd64
Revision: 553cfa1f9f99f4da6118f93d507294e580db00d7
CGO: disabled

Description

Since sing-box 1.13.11, a DoT DNS query can fail after the upstream TLS connections have been idle and closed by the remote server.

With two concurrent warm-up DNS queries, sing-box keeps two DoT connections in the pool. After a short idle period, the next single DNS query may reuse both stale pooled connections. Both attempts return EOF, then the DNS exchange fails and the client times out.

The same reproduction succeeds on 1.13.10: it logs one stale pooled connection EOF, then opens a new TLS connection and returns the DNS response.

Reproduction

curl -fL -o sing-box-1.13.11-linux-amd64.tar.gz \
  https://github.com/SagerNet/sing-box/releases/download/v1.13.11/sing-box-1.13.11-linux-amd64.tar.gz
tar -xzf sing-box-1.13.11-linux-amd64.tar.gz
cd sing-box-1.13.11-linux-amd64

cat > config.json <<'JSON'
{
  "log": {
    "level": "debug"
  },
  "dns": {
    "servers": [
      {
        "type": "tls",
        "server": "1.1.1.1"
      }
    ],
    "disable_cache": true
  },
  "inbounds": [
    {
      "type": "direct",
      "listen": "127.0.0.1",
      "listen_port": 55754,
      "network": "udp"
    }
  ],
  "route": {
    "rules": [
      {
        "action": "hijack-dns"
      }
    ]
  }
}
JSON

./sing-box run -c config.json --disable-color 2> sing-box.err &
pid=$!

sleep 2.5

kdig +timeout=8 +retry=0 +noall +answer -p 55754 www.cloudflare.com A @127.0.0.1 &
p1=$!
kdig +timeout=8 +retry=0 +noall +answer -p 55754 www.cloudflare.com AAAA @127.0.0.1 &
p2=$!
wait "$p1" || true
wait "$p2" || true

sleep 10

kdig +timeout=8 +retry=0 +noall +answer +stats -p 55754 www.cloudflare.com A @127.0.0.1

kill "$pid"
grep -E 'discarded pooled connection|exchange failed for' sing-box.err

Logs

# sing-box 1.13.11 result:
;; WARNING: response timeout for 127.0.0.1@55754(UDP)
;; ERROR: failed to query server 127.0.0.1@55754(UDP)

DEBUG[0012] dns/tls[0]: discarded pooled connection: read response: EOF
DEBUG[0012] dns/tls[0]: discarded pooled connection: read response: EOF
ERROR[0012] dns: exchange failed for www.cloudflare.com. IN A: read response: EOF

# sing-box 1.13.10 with the same config/procedure:
# The query succeeds after one stale pooled connection is discarded.

DEBUG[0012] dns/tls[0]: discarded pooled connection: read response: EOF

Supporter

Integrity requirements

  • 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.
  • I confirm that I have provided the server and client configuration files and process that can be reproduced locally, instead of a complicated client configuration file that has been stripped of sensitive data.
  • I confirm that I have provided the simplest configuration that can be used to reproduce the error I reported, instead of depending on remote servers, TUN, graphical interface clients, or other closed-source software.
  • I confirm that I have provided the complete configuration files and logs, rather than just providing parts I think are useful out of confidence in my own intelligence.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    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