Skip to content

Managed ECH HTTPS records omit ALPN, causing clients to prefer h2 over h3 #7667

@h3nnes

Description

@h3nnes

Issue Details

Short description

When using Caddy with ECH enabled, h3 breaks and clients fall back to h2.
There are QUIC errors, as shown in the attached 'https-record-h2-fallback.txt' curl log.
While debugging, I removed the HTTPS record and restarted Caddy with the ECH configuration still enabled in Caddyfile. After that, h3 connections started working again, as can be seen in the 'no-https-record-h3-works.txt' curl log.

Setup

  • Caddy version:
v2.11.3-0.20260421185931-aed1af59763d h1:mZleOSpQzf10ACi1frV+ZLeX7t1XgI1FzKga3KxCuKk=`
  • Caddy compile command:
./xcaddy build master --with github.com/caddy-dns/cloudflare@master --output caddy
  • golang version:
go version go1.25.0 linux/amd64
  • DNS records:
$ dig ech.h-neef.de
89.144.8.160

$ dig speed.h-neef.de
89.144.8.160

$ dig +short @cloudflare-dns.com +https HTTPS speed.h-neef.de
2 . ech=AEj+DQBEzQAgACBVpRfw+C+q3Mq5XAwSxVEbY1Unray6SACeDyfhd1t4OAAMAAEAAQABAAIAAQADHQ1lY2guaC1uZWVmLmRlAAA=
  • Debian 13 amd64 VPS

  • Open FW ports 80,443 (TCP/UDP)

  • Minimal Caddyfile to reproduce:

{
    debug
    acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
    dns cloudflare {env.CLOUDFLARE_API_TOKEN}
    ech ech.h-neef.de
}

speed.h-neef.de {
    respond "Hi!"
}

Steps to reproduce

  1. Build newest Caddy with a DNS provider
  2. Take the attached ECH-enabled Caddyfile and modify domains and global DNS config
  3. Make a request to your site, it will use h2 as the protocol
  4. After that, either just remove the HTTPS record for the domain and restart Caddy, or remove the HTTPS records, remove the ECH config in Caddyfile and restart Caddy
  5. Make a new request to your site, it will use h3 as the protocol

Logs

Attached the two logs from http3 and ECH enabled curl.

https-record-h2-fallback.txt

no-https-record-h3-works.txt

The first log file https-record-h2-fallback.txt contains the first request while Caddy was correctly configured with ECH and there was an existing HTTPS DNS records. h3 was attempted, but failed and clients fell back to h2.
The second log file no-https-record-h3-works.txt contains the second request after the HTTPS DNS record was removed at my DNS provider and Caddy was restarted (with ECH config still in Caddyfile).

Assistance Disclosure

AI not used

If AI was used, describe the extent to which it was used.

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug 🐞Something 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