Skip to content

Bug: panic: index out of range in DNS-over-TLS pool (latest build 2026-04-19, commit 17a7bf6) #3292

@nufnuf37

Description

@nufnuf37

Is this urgent?

None

Host OS

debian

CPU arch

x86_64

VPN service provider

ProtonVPN

What are you using to run the container

Other

What is the version of Gluetun

latest build 2026-04-19T18:07:14.380Z (commit 17a7bf6)

What's the problem 🤔

Bug report

Gluetun version

latest build 2026-04-19T18:07:14.380Z (commit 17a7bf6)

Description

The latest build from April 19, 2026 causes a panic in the DNS-over-TLS connection pool, crashing gluetun repeatedly and taking down all containers sharing its network namespace (e.g. qbittorrent with network_mode: service:gluetun).

Steps to reproduce

  1. Pull qmcgaw/gluetun:latest (build 17a7bf6, April 19, 2026)
  2. Start gluetun with default DNS settings (DoT enabled, upstream: Cloudflare)
  3. After a few minutes, gluetun panics and exits with code 0
  4. On restart, the panic occurs again → crash loop

Full logs

2026-04-20T01:25:16+02:00 WARN [dns] getting tls connection for request IN A ifconfig.io.: renewing dead connection: running TLS handshake with 1.0.0.1:853 (cloudflare-dns.com): read tcp 10.96.0.3:48878->1.0.0.1:853: read: connection reset by peer
2026-04-20T01:25:16+02:00 WARN [dns] getting tls connection for request IN A opentracker.io.: creating connection: running TLS handshake with 1.0.0.1:853 (cloudflare-dns.com): read tcp 10.96.0.3:48900->1.0.0.1:853: read: connection reset by peer
2026-04-20T01:25:16+02:00 WARN [dns] getting tls connection for request IN AAAA ifconfig.io.: renewing dead connection: running TLS handshake with 1.1.1.1:853 (cloudflare-dns.com): read tcp 10.96.0.3:46020->1.1.1.1:853: read: connection reset by peer
2026-04-20T01:25:16+02:00 WARN [dns] getting tls connection for request IN AAAA opentracker.io.: creating connection: running TLS handshake with 1.0.0.1:853 (cloudflare-dns.com): read tcp 10.96.0.3:48886->1.0.0.1:853: read: connection reset by peer
2026-04-20T01:25:20+02:00 WARN [dns] getting tls connection for request IN AAAA www.torrent.eu.org.: creating connection: running TLS handshake with 1.0.0.1:853 (cloudflare-dns.com): read tcp 10.96.0.3:48952->1.0.0.1:853: read: connection reset by peer
2026-04-20T01:25:20+02:00 WARN [dns] getting tls connection for request IN A www.torrent.eu.org.: creating connection: running TLS handshake with 1.0.0.1:853 (cloudflare-dns.com): read tcp 10.96.0.3:48960->1.0.0.1:853: read: connection reset by peer
panic: runtime error: index out of range [0] with length 0

goroutine 935 [running]:
github.com/qdm12/dns/v2/internal/pool.(*Pool).renew(0xc000f03ec0, {0x1605218, 0xc00107a000}, {{0x1609910, 0xc000352008}, 0x1, 0x0, {0xc27176ef21761787, 0x256e4e231, 0x1b6f0c0}, ...}, ...)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/internal/pool/renew.go:66 +0x612
github.com/qdm12/dns/v2/internal/pool.(*Pool).Get(0xc000f03ec0, {0x1605218, 0xc00107a000}, {0xd179e2, 0x3})
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/internal/pool/get.go:68 +0x6d1
github.com/qdm12/dns/v2/internal/exchanger.(*Exchanger).exchangeWithPool(0xc000f03f20, {0x1605218, 0xc00107a000}, {0xd179e2, 0x3}, 0xc008c56000)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/internal/exchanger/exchanger.go:60 +0x56
github.com/qdm12/dns/v2/internal/exchanger.(*Exchanger).Exchange(0xc001f525a0?, {0x1605218?, 0xc00107a000?}, {0xd179e2?, 0xc38880?}, 0x0?)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/internal/exchanger/exchanger.go:52 +0x28
github.com/qdm12/dns/v2/pkg/server.(*handler).ServeDNS(0xc00019bec0, {0x160bbd8, 0xc001f525a0}, 0xc008c56000)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/pkg/server/handler.go:32 +0x53
github.com/qdm12/dns/v2/pkg/middlewares/cache.(*handler).ServeDNS(0xc000593440, {0x160bbd8, 0xc001f52598}, 0xc008c56000)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/pkg/middlewares/cache/middleware.go:54 +0x155
github.com/qdm12/dns/v2/pkg/middlewares/filter.(*handler).ServeDNS(0xc000593460, {0x160ba00, 0xc000523c80}, 0xc008c56000)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/pkg/middlewares/filter/middleware.go:55 +0x15c
github.com/qdm12/dns/v2/pkg/middlewares/localdns.(*handler).ServeDNS(0xc00023e6c0, {0x160ba00, 0xc000523c80}, 0xc008c56000)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/pkg/middlewares/localdns/handler.go:110 +0x16e
github.com/miekg/dns.(*Server).serveDNS(0xc0000fb200, {0xc000254e00, 0x21, 0x200}, 0xc000523c80)
        github.com/miekg/dns@v1.1.62/server.go:680 +0x44a
github.com/miekg/dns.(*Server).serveUDPPacket(0xc0000fb200, 0xc0004ee590, {0xc000254e00, 0x21, 0x200}, {0x1608ed0, 0xc00006ed98}, 0xc000b29b20, {0x0, 0x0})
        github.com/miekg/dns@v1.1.62/server.go:621 +0x1a5
created by github.com/miekg/dns.(*Server).serveUDP in goroutine 626
        github.com/miekg/dns@v1.1.62/server.go:551 +0x41a
gluetun exited with code 0

Root cause

The panic occurs in github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/internal/pool/renew.go:66 when the DoT connection pool tries to renew a dead TLS connection and receives an empty slice, causing an index out of bounds panic.

The TLS connections to Cloudflare DoT (1.0.0.1:853 / 1.1.1.1:853) are reset by the VPN server, leaving the pool in an invalid state that triggers the panic on the next renewal attempt.

Workaround

Two options:

  • Set DNS_OVER_TLS=off to disable DoT (avoids the panic but loses DNS encryption)
  • Downgrade to qmcgaw/gluetun:v3.41.0 (stable, not affected)

Environment

  • Host OS: Debian/Proxmox (Linux 6.17.13-2-pve x86_64)
  • Docker Compose: gluetun + qbittorrent with network_mode: service:gluetun
  • VPN provider: ProtonVPN (OpenVPN UDP, Netherlands servers)
  • Only affects latest build from April 19, 2026 (commit 17a7bf6) — v3.41.0 is not affected

Share your logs (at least 10 lines)

2026-04-20T01:25:16+02:00 WARN [dns] getting tls connection for request IN A ifconfig.io.: renewing dead connection: running TLS handshake with 1.0.0.1:853 (cloudflare-dns.com): read tcp 10.96.0.3:48878->1.0.0.1:853: read: connection reset by peer
2026-04-20T01:25:16+02:00 WARN [dns] getting tls connection for request IN A opentracker.io.: creating connection: running TLS handshake with 1.0.0.1:853 (cloudflare-dns.com): read tcp 10.96.0.3:48900->1.0.0.1:853: read: connection reset by peer
2026-04-20T01:25:16+02:00 WARN [dns] getting tls connection for request IN AAAA ifconfig.io.: renewing dead connection: running TLS handshake with 1.1.1.1:853 (cloudflare-dns.com): read tcp 10.96.0.3:46020->1.1.1.1:853: read: connection reset by peer
2026-04-20T01:25:16+02:00 WARN [dns] getting tls connection for request IN AAAA opentracker.io.: creating connection: running TLS handshake with 1.0.0.1:853 (cloudflare-dns.com): read tcp 10.96.0.3:48886->1.0.0.1:853: read: connection reset by peer
2026-04-20T01:25:20+02:00 WARN [dns] getting tls connection for request IN AAAA www.torrent.eu.org.: creating connection: running TLS handshake with 1.0.0.1:853 (cloudflare-dns.com): read tcp 10.96.0.3:48952->1.0.0.1:853: read: connection reset by peer
2026-04-20T01:25:20+02:00 WARN [dns] getting tls connection for request IN A www.torrent.eu.org.: creating connection: running TLS handshake with 1.0.0.1:853 (cloudflare-dns.com): read tcp 10.96.0.3:48960->1.0.0.1:853: read: connection reset by peer
panic: runtime error: index out of range [0] with length 0

goroutine 935 [running]:
github.com/qdm12/dns/v2/internal/pool.(*Pool).renew(0xc000f03ec0, {0x1605218, 0xc00107a000}, {{0x1609910, 0xc000352008}, 0x1, 0x0, {0xc27176ef21761787, 0x256e4e231, 0x1b6f0c0}, ...}, ...)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/internal/pool/renew.go:66 +0x612
github.com/qdm12/dns/v2/internal/pool.(*Pool).Get(0xc000f03ec0, {0x1605218, 0xc00107a000}, {0xd179e2, 0x3})
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/internal/pool/get.go:68 +0x6d1
github.com/qdm12/dns/v2/internal/exchanger.(*Exchanger).exchangeWithPool(0xc000f03f20, {0x1605218, 0xc00107a000}, {0xd179e2, 0x3}, 0xc008c56000)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/internal/exchanger/exchanger.go:60 +0x56
github.com/qdm12/dns/v2/internal/exchanger.(*Exchanger).Exchange(0xc001f525a0?, {0x1605218?, 0xc00107a000?}, {0xd179e2?, 0xc38880?}, 0x0?)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/internal/exchanger/exchanger.go:52 +0x28
github.com/qdm12/dns/v2/pkg/server.(*handler).ServeDNS(0xc00019bec0, {0x160bbd8, 0xc001f525a0}, 0xc008c56000)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/pkg/server/handler.go:32 +0x53
github.com/qdm12/dns/v2/pkg/middlewares/cache.(*handler).ServeDNS(0xc000593440, {0x160bbd8, 0xc001f52598}, 0xc008c56000)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/pkg/middlewares/cache/middleware.go:54 +0x155
github.com/qdm12/dns/v2/pkg/middlewares/filter.(*handler).ServeDNS(0xc000593460, {0x160ba00, 0xc000523c80}, 0xc008c56000)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/pkg/middlewares/filter/middleware.go:55 +0x15c
github.com/qdm12/dns/v2/pkg/middlewares/localdns.(*handler).ServeDNS(0xc00023e6c0, {0x160ba00, 0xc000523c80}, 0xc008c56000)
        github.com/qdm12/dns/v2@v2.0.0-rc9.0.20260418231648-0418ff535211/pkg/middlewares/localdns/handler.go:110 +0x16e
github.com/miekg/dns.(*Server).serveDNS(0xc0000fb200, {0xc000254e00, 0x21, 0x200}, 0xc000523c80)
        github.com/miekg/dns@v1.1.62/server.go:680 +0x44a
github.com/miekg/dns.(*Server).serveUDPPacket(0xc0000fb200, 0xc0004ee590, {0xc000254e00, 0x21, 0x200}, {0x1608ed0, 0xc00006ed98}, 0xc000b29b20, {0x0, 0x0})
        github.com/miekg/dns@v1.1.62/server.go:621 +0x1a5
created by github.com/miekg/dns.(*Server).serveUDP in goroutine 626
        github.com/miekg/dns@v1.1.62/server.go:551 +0x41a
gluetun exited with code 0

Share your configuration

networks:
  media:
    external: true
  vpn_net:
    external: true
    internal: true

volumes:
  gluetun_state: {}

services:
  gluetun:
    image: qmcgaw/gluetun
    container_name: gluetun
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    environment:
      - VPN_SERVICE_PROVIDER=protonvpn
      - VPN_TYPE=openvpn
      - OPENVPN_USER=${PROTON_USER}
      - OPENVPN_PASSWORD=${PROTON_PASS}
      - SERVER_COUNTRIES=Netherlands
      - SERVER_PF_ONLY=on
      - VPN_PORT_FORWARDING=on
      - PORT_FORWARDING=on
      - FIREWALL_INPUT_PORTS=8080
      - TZ=Europe/Paris
    volumes:
      - gluetun_state:/tmp/gluetun
      - /srv/media-ops/appdata/gluetun:/gluetun
    healthcheck:
      test:
        - CMD
        - sh
        - -c
        - wget -qO- https://ifconfig.io || exit 1
      interval: 30s
      timeout: 5s
      retries: 10
    networks:
      - vpn_net
    restart: unless-stopped

  qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:latest
    container_name: qbittorrent
    network_mode: service:gluetun
    depends_on:
      gluetun:
        condition: service_healthy
    environment:
      PUID: "3000"
      PGID: "3000"
      TZ: Europe/Paris
      WEBUI_PORT: "8080"
    volumes:
      - /srv/media-ops/appdata/qbittorrent:/config
      - /mnt/plex:/mnt/plex
      - /mnt/plex/downloads:/downloads
    restart: unless-stopped

  qb-port-sync:
    image: curlimages/curl:8.8.0
    container_name: qb-port-sync
    network_mode: service:gluetun
    depends_on:
      gluetun:
        condition: service_healthy
      qbittorrent:
        condition: service_started
    environment:
      QBT_URL: http://127.0.0.1:8080
      QBT_USER: 
      QBT_PASS: 
      INTERVAL: "30"
    volumes:
      - /srv/media-ops/appdata/qb-port-sync:/work:ro
      - gluetun_state:/tmp/gluetun:ro
    entrypoint:
      - /bin/sh
      - -c
      - /work/sync.sh
    restart: unless-stopped

  qb-webui-proxy:
    image: nginx:alpine
    container_name: qb-webui-proxy
    depends_on:
      gluetun:
        condition: service_started
      qbittorrent:
        condition: service_started
    networks:
      - vpn_net
      - media
    ports:
      - 8080:8080
    volumes:
      - /srv/media-ops/appdata/qb-webui-proxy/default.conf:/etc/nginx/conf.d/default.conf:ro
    restart: unless-stopped

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions