Retour au Blog

Post-Quantum DNSSEC Just Got Real: The 2,420-Byte Runbook for Game Backend Operators

Publié le 11 septembre 2026
Post-Quantum DNSSEC Just Got Real: The 2,420-Byte Runbook for Game Backend Operators Généré avec l'aide de l'IA

En bref

Post-quantum DNSSEC signatures are 38x larger than ECDSA. Learn how the 2,420-byte ML-DSA-44 problem affects game backend DNS resolution — and how to prepare your infrastructure.

DNS resolution just got 38x bigger

Every millisecond your game waits for DNS resolution before connecting players to your backend is a millisecond they spend staring at a loading screen. On September 3rd, Cloudflare's 1.1.1.1 resolver began validating DNSSEC signatures made with ML-DSA-44 — a post-quantum signature algorithm standardized by NIST. Each ML-DSA-44 signature is 2,420 bytes, nearly 38 times the size of the ECDSA P-256 signatures (64 bytes) that most DNSSEC-secured zones use today.

If you operate custom domains for your game backend, matchmaker, CDN, or asset-delivery endpoints, this change will eventually reshape your DNS infrastructure. Concrete impacts:

  • DNS responses that comfortably fit in a single UDP packet today will exceed the 1,232-byte conservative UDP payload limit
  • Authoritative servers will return truncated responses, forcing TCP retries
  • Zones running dual algorithms during the migration window introduce downgrade-attack surfaces
  • All of this adds latency to the first network hop your players make

This is a runbook for detecting, mitigating, and preparing for post-quantum DNSSEC in game backend infrastructure.

Why game backends care about DNSSEC signature sizes

The UDP size wall

DNS over UDP has a long history of packet-size constraints:

Limit Source Bytes
Original DNS UDP max RFC 1035 (1987) 512
EDNS(0) common default Various implementations 1,232
Recommended maximum RFC 9715 (2025) 1,400
ML-DSA-44 signature alone NIST ML-DSA-44 2,420
ML-DSA-44 public key DNSKEY RRset 1,312

A single ML-DSA-44 signature exceeds every one of these limits by itself, before adding the signed RRset, domain names, headers, and other DNSSEC records. Fragmented UDP is unreliable — Cloudflare and others have explicitly recommended against it since DNS Flag Day 2020 — so the practical fallback is TCP.

What TCP fallback costs your players

According to Cloudflare Radar, roughly 85% of queries to 1.1.1.1 arrive over UDP. Across all services on their Big Pineapple platform (which also powers Gateway DNS), about 60% arrive over UDP. That means 15–40% of DNS traffic already uses TCP, DoT, or DoH — but those are voluntary non-UDP connections.

When UDP fails and the client retries over TCP, you pay a full TCP handshake penalty: ~1 RTT for SYN/SYN-ACK/ACK before the resolver even sends the query. For a player connecting to your game backend from 80ms away, that is an additional 80ms of connection time before authentication even starts.

In practice, TCP fallback happens between the resolver and the authoritative nameserver, and the resolver caches results. The pain is worst when:

  1. The cache is cold — first lookup after TTL expires, or a new player connecting in a region with no prior traffic
  2. The zone's DNSKEY response is large — exactly the case during the dual-algorithm migration period
  3. Multiple delegations produce large responses — a chain of 3–4 zones, each carrying both conventional and post-quantum keys

Session launch timeouts already plague multiplayer backends under normal DNS conditions — we covered the diagnostics for Unreal Engine network-level timeout issues in a previous deep-dive. Post-quantum DNSSEC will make these timeouts more prevalent if you do not plan for the larger responses.

The dual-algorithm migration trap

ML-DSA-44 cannot fully replace conventional signing algorithms overnight. Zones must publish both conventional (ECDSA/RSA) and post-quantum (ML-DSA-44) keys for backward compatibility. During this window, the DNSKEY response for a zone may contain:

  • The conventional public key (e.g., 91 bytes for ECDSA P-256)
  • The ML-DSA-44 public key (1,312 bytes)
  • The conventional signature over the DNSKEY RRset (64 bytes)
  • The ML-DSA-44 signature over the DNSKEY RRset (2,420 bytes)

That is roughly 3,900 bytes of DNSSEC material alone, well beyond any UDP payload limit. Key rollovers add still more. The resolver must fall back to TCP.

The downgrade attack surface

Here is the security concern that makes this more than a latency problem. RFC 6840 says validators "SHOULD accept any single valid path." This means if a zone publishes both an ECDSA and an ML-DSA-44 validator set, a resolver that supports both will accept either one.

Once quantum computers can break ECDSA keys, an attacker can forge ECDSA-only responses and a post-quantum-capable resolver will still accept them. This is the downgrade attack:

  1. A player's resolver queries api.your-game-backend.com and receives a response signed with ECDSA only
  2. The resolver accepts the ECDSA signature because it is on the "any valid path" list
  3. The attacker has forged this response using a quantum-derived private key
  4. The player connects to the attacker's server instead of yours

This is not a theoretical concern. The Star Citizen data breach demonstrated how a single infrastructure compromise can cascade into massive credential leaks. A DNS-level compromise is worse: it redirects every player who resolves your hostname to an attacker-controlled endpoint.

1.1.1.1 addresses this by using the DS record as an authenticated signal: if the parent zone's DS RRset contains a record for a supported post-quantum algorithm, the resolver enforces a stricter policy requiring at least one valid post-quantum validation path. If no ML-DSA-44 path validates, validation fails entirely.

This is good — but it means zones that intend to offer post-quantum security need to publish ML-DSA-44 DS records, and every delegation above them in the chain must do the same. A compromised key anywhere in the chain lets an attacker forge everything below it: "break once, forge everywhere."

Detecting post-quantum DNSSEC impact on your infrastructure

Step 1: Check current DNS response sizes

Before you can measure the impact, you need a baseline. Use dig with the +dnssec flag to see current response sizes for your game's domains:

# Measure current DNSKEY response size for your authoritative zone
dig +dnssec +bufsize=4096 NS your-game-backend.com @your-ns.example.com +short

# Check the full DNSKEY response with size tracking
dig +dnssec +bufsize=4096 DNSKEY your-game-backend.com @your-ns.example.com
# Look at the MSG SIZE stat near the bottom of the output

# Measure a typical A-record query with DNSSEC signatures attached
dig +dnssec +bufsize=4096 A api.your-game-backend.com @your-ns.example.com

For reference, a DNSKEY response with ECDSA P-256 produces roughly 200–400 bytes. With ML-DSA-44 published alongside, expect 3,500–5,000 bytes. Record your current numbers — you will need them to detect degradation.

Step 2: Check which algorithm your zone uses

# Extract algorithm numbers from your DNSKEY records
dig +dnssec DNSKEY your-game-backend.com @your-ns.example.com | \
  grep -E "DNSKEY|RRSIG" | awk '{print $5}' | sort -u

The algorithm number tells you the signing algorithm in use:

Algorithm Number Status
RSA/SHA-256 8 Widely used, quantum-vulnerable
ECDSA P-256/SHA-256 13 Most common modern choice, quantum-vulnerable
ED448 16 Quantum-vulnerable but large (~114 bytes)
ML-DSA-44 18 Post-quantum, 2,420 bytes, newly assigned by IANA

If your zone currently uses algorithm 13 (ECDSA P-256), you are on the most common modern hairline. Migration to algorithm 18 is in the planning stage for most of the DNS ecosystem — but you should understand the timeline.

Step 3: Monitor TCP fallback rates with a query-log analyzer

If you run authoritative nameservers or have resolver log access, track the ratio of TCP to UDP queries. This is the clearest early signal that response sizes are hitting the UDP wall.

#!/usr/bin/env python3
"""
Post-Quantum DNSSEC TCP Fallback Monitor.
Tracks TCP/UDP query ratios from BIND-style query logs
as a proxy for large-response fallback pressure.

Usage:
    python3 pq_dns_monitor.py --log /var/log/named/queries.log --window 2
"""

import re
import argparse
from collections import Counter
from datetime import datetime, timedelta

LOG_PATTERN = re.compile(
    r"(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})\.\d+Z"
    r"\s+(\w+)\s+query:\s+\S+\s+(\S+)\s+(\S+)"
)

def analyze_dns_traffic(log_path: str, window_hours: int = 1) -> None:
    cutoff = datetime.utcnow() - timedelta(hours=window_hours)
    transport_counts = Counter()
    rrtype_counts = Counter()
    tcp_by_qtype: Counter = Counter()

    with open(log_path, "r") as f:
        for line in f:
            m = LOG_PATTERN.search(line)
            if not m:
                continue
            ts_str, transport, qname, qtype = m.groups()
            try:
                ts = datetime.strptime(ts_str, "%Y-%m-%dT%H:%M:%S")
                if ts < cutoff:
                    continue
            except ValueError:
                continue

            transport_counts[transport] += 1
            rrtype_counts[qtype] += 1
            if transport == "tcp":
                tcp_by_qtype[qtype] += 1

    total = sum(transport_counts.values())
    if total == 0:
        print("No queries found in the specified time window.")
        return

    tcp_count = transport_counts.get("tcp", 0)
    tcp_pct = (tcp_count / total) * 100

    print(f"=== DNS Transport Breakdown (last {window_hours}h) ===")
    print(f"  UDP: {transport_counts.get('udp', 0):>8} ({100 - tcp_pct:.1f}%)")
    print(f"  TCP: {tcp_count:>8} ({tcp_pct:.1f}%)")
    print(f"  Total: {total:>6}")
    print()

    if tcp_pct > 15.0:
        print(f"  ⚠  ALERT: TCP fallback rate is {tcp_pct:.1f}%.")
        print("     Large DNSSEC responses may be forcing TCP retries.")
        print("     Check whether any upstream zones have added post-quantum keys.")
    elif tcp_pct > 8.0:
        print(f"  ⚡ NOTICE: TCP fallback rate is {tcp_pct:.1f}%. Monitor for increases.")
    else:
        print(f"  ✓  TCP fallback rate ({tcp_pct:.1f}%) is within normal range.")

    # Show which query types incur the most TCP fallback
    if tcp_by_qtype:
        print()
        print("=== TCP Fallback by Query Type ===")
        for qtype, count in tcp_by_qtype.most_common(5):
            pct = (count / rrtype_counts[qtype]) * 100 if rrtype_counts[qtype] else 0
            print(f"  {qtype:<10} {count:>5} TCP / {rrtype_counts[qtype]:>5} total  ({pct:.0f}%)")

    print()
    print("=== Query Type Breakdown ===")
    for qtype, count in rrtype_counts.most_common(10):
        print(f"  {qtype:<10} {count:>6}")

    # Recommendation
    print()
    if tcp_by_qtype.get("DNSKEY", 0) > tcp_by_qtype.get("A", 0) * 0.5:
        print("  ➜  DNSKEY queries have a notably high TCP fallback rate.")
        print("     Your zones or upstream zones may already be publishing")
        print("     large post-quantum keys alongside conventional ones.")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="DNS TCP fallback monitor for PQ-DNSSEC readiness")
    parser.add_argument("--log", required=True, help="Path to BIND query log file")
    parser.add_argument("--window", type=int, default=1, help="Time window in hours")
    args = parser.parse_args()
    analyze_dns_traffic(args.log, args.window)

Run this against your authoritative nameserver logs regularly. If TCP queries for DNSKEY or DS records trend above 10%, your resolvers are hitting the UDP wall and post-quantum-sized responses are the likely cause.

Step 4: Benchmark resolver-to-authoritative latency

Use dnsperf to stress-test your authoritative server's response times under load, including queries that trigger large responses:

# Create a test query file focused on DNSSEC-heavy queries
cat > /tmp/dnssec-bench.txt << 'EOF'
your-game-backend.com DNSKEY
your-game-backend.com DNS
api.your-game-backend.com A
match.your-game-backend.com A
assets.your-game-backend.com A
EOF

# Run with 20 concurrent clients for 20 seconds
dnsperf -s your-ns-ip -d /tmp/dnssec-bench.txt -l 20 -c 20

Compare average latency and TCP truncation rates before and after adding ML-DSA-44 records to a test zone. You want measurable numbers, not guesswork.

Remediation: Hardening your DNS for post-quantum responses

1. Maximize EDNS(0) buffer sizes on authoritative servers

Your authoritative nameservers should advertise the largest UDP payload they support. This does not prevent TCP fallback for DNSKEY responses — ML-DSA-44 signatures are simply too large — but it ensures non-DNSSEC responses and smaller signatures still fit in UDP, and it gets the truncation signal to clients faster.

# BIND 9 — named.conf
options {
    edns-udp-size 1232;
    max-udp-size 1232;
    tcp-fast-open 256;
};

The 1,232-byte setting is chosen specifically: 1,280 (IPv6 minimum MTU) − 40 (IPv6 header) − 8 (UDP header) = 1,232. This prevents fragmentation on any path that supports IPv6's minimum MTU.

# NSD — nsd.conf
server:
    ipv4-edns-size: 1232
    ipv6-edns-size: 1232

2. Enable TCP Fast Open on all nameservers you control

TCP Fast Open (TFO) lets the resolver send the DNS query in the SYN packet, eliminating one round trip from the TCP connection setup. This cuts TCP fallback from ~2 RTT (handshake + query/response) to ~1 RTT.

# Linux: enable TFO for both inbound and outbound connections (mode 3)
sudo sysctl -w net.ipv4.tcp_fastopen=3

# Verify
cat /proc/sys/net/ipv4/tcp_fastopen
# Expected output: 3

TFO must also be enabled in your DNS software. BIND 9 (9.18+) and Knot Resolver support it. Check your version's documentation. For Unbound, it is enabled by default in recent builds.

The net effect: a TCP DNS query that previously cost ~160ms (two 80ms round trips) now costs ~80ms (one round trip). This is still worse than UDP (~80ms), but the penalty is halved.

3. Resolve and cache hostnames at game startup — never during gameplay

The single most effective mitigation for DNS latency in game clients is to avoid performing DNS lookups during gameplay-critical paths. Resolve all backend hostnames at initialization and cache the resolved IP addresses for the session lifetime.

// Unreal Engine C++ — resolve game backend hostnames at startup
// and cache IP addresses so players never wait for DNS during connect

void UGameBackendSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
    Super::Initialize(Collection);

    // All hostnames the game needs during a session
    TArray<FString> Hostnames = {
        TEXT("api.your-game-backend.com"),
        TEXT("match.your-game-backend.com"),
        TEXT("assets.cdn.your-game-backend.com"),
    };

    ISocketSubsystem* Sockets = ISocketSubsystem::Get();

    for (const FString& Host : Hostnames)
    {
        // Resolve at startup — resolves once, not on first connect
        FResolveInfo* ResolveInfo = Sockets->GetHostByName(
            TCHAR_TO_ANSI(*Host)
        );

        // Block until resolution completes (acceptable during loading screen)
        ResolveInfo->WaitUntilComplete(5.0f);

        FInternetAddr Result;
        if (ResolveInfo->GetErrorCode() == 0)
        {
            Result = ResolveInfo->GetResolvedAddress();
            FString ResolvedIP = Result.ToString(false);
            CachedEndpoints.Add(Host, ResolvedIP);
            UE_LOG(LogGameBackend, Log,
                TEXT("Pre-resolved %s -> %s (cached for session)"),
                *Host, *ResolvedIP);
        }
        else
        {
            UE_LOG(LogGameBackend, Warning,
                TEXT("DNS resolution failed for %s (error %d)"),
                *Host, ResolveInfo->GetErrorCode());
            // Store empty — will re-resolve on demand with exponential backoff
            CachedEndpoints.Add(Host, FString());
        }
    }
}

FString UGameBackendSubsystem::GetResolvedAddress(const FString& Hostname) const
{
    const FString* Cached = CachedEndpoints.Find(Hostname);
    if (Cached && !Cached->IsEmpty())
    {
        return *Cached;
    }
    return Hostname; // Fallback to hostname (will trigger real DNS)
}

This means your players never wait for DNS during connect-to-server or asset-download flows. Even if DNS resolution takes 200ms due to TCP fallback and a cold cache, it happens silently during the loading screen — not during the matchmaking countdown.

4. Use DNS-over-HTTPS for infrastructure queries

DoH runs over HTTP/2 or HTTP/3 (both TCP-based or QUIC-based at the transport layer), so it bypasses the UDP size limitation entirely. If your game backend servers, deployment scripts, or CI/CD pipelines query DNS programmatically, configure them for DoH:

# Resolve a hostname using Cloudflare's DoH endpoint
# (requires curl 7.76+)
curl -sS \
  "https://cloudflare-dns.com/dns?name=api.your-game-backend.com&type=A" \
  -H "Accept: application/dns-json" | jq -r '.Answer[0].data'

# For Kubernetes pods, configure CoreDNS to forward to a DoH-capable
# recursive resolver. In practice, this means setting upstream to
# a resolver that natively supports DoH, such as 1.1.1.1 or 8.8.8.8

This is particularly relevant for health-check scripts monitoring backend availability, deployment verification pipelines, and container orchestration systems where pods default to the node's resolver configuration.

5. Audit your zone's DS records and algorithm readiness

If you operate your own authoritative zone, check that your DS records match your current algorithm and that you are not carrying stale delegation data.

# Check DS records from the parent zone
dig +short DS your-game-backend.com

# Compare with actual DNSKEY data in your zone
dig +short DNSKEY your-game-backend.com

# Use delv to trace the full DNSSEC validation chain
delv +rtrace api.your-game-backend.com A

If you see orphaned DS records for algorithms you no longer use, they can cause unnecessary fallback logic in resolvers. Clean them up during your next maintenance window.

Best practices: A post-quantum DNSSEC readiness checklist

  1. Baseline your DNS response sizes today. Run dig +dnssec against all zones your infrastructure depends on. Record MSG SIZE for DNSKEY, DS, and typical A-record queries. You need these numbers to detect future degradation when upstream zones begin publishing post-quantum records.

  2. Enable TCP Fast Open on every nameserver you control. This single kernel flag change cuts TCP fallback latency by one full round trip (~80–160ms depending on geography). Combined with aggressive DNS caching, it makes TCP fallback nearly invisible to players.

  3. Resolve hostnames at game startup, never during gameplay. All backend, CDN, and matchmaker endpoints should resolve during the loading screen and cache in memory. Background refresh every few minutes handles TTL expiry without blocking gameplay.

  4. Monitor TCP fallback rates weekly. Set up the query-log analyzer above or equivalent. A sustained TCP rate above 10% for DNSKEY queries signals that response sizes are exceeding UDP limits. Treat this as you would a latency SLA breach.

  5. Plan your DNSSEC algorithm migration timeline. If you sign your own zone, begin testing ML-DSA-44 in a staging subdomain. Publish dual-algorithm keys and measure the response size impact. Do not wait for a quantum threat to emerge — migration in DNS is measured in years, not sprints. Algorithm migration in DNSSEC is an infrastructure-level concern, and the security of your accounts, leaderboards, and cloud save data depends on the integrity of the resolution paths that deliver your players to those services in the first place.

The timeline: When this matters for you

Cloudflare's 1.1.1.1 enabling ML-DSA-44 validation is the first major resolver deployment. Here is the rough timeline:

Period What happens
Now (2025) Cloudflare 1.1.1.1 validates ML-DSA-44; early adopters begin testing
2025–2027 More resolvers add validation; early zones begin publishing dual-algorithm keys
2027–2029 Wider zone adoption; resolvers may enforce stricter downgrade-protection policies
2029+ Cloudflare targets full post-quantum security; conventional algorithms considered insecure

None of this will break your game servers tomorrow. But the migration pattern is clear.

The game backend operators who start preparing now — caching DNS, enabling TFO, auditing zone algorithms, monitoring TCP fallback rates — will not notice when this transition completes. The ones who wait will be debugging TCP fallback latency and DNSSEC validation failures during a live game launch, which is exactly when you can least afford it.

Ready to focus on building gameplay instead of managing infrastructure? horizOn handles account authentication, cloud save, leaderboards, and crash reporting so you can dedicate your infrastructure effort to the DNS, networking, and security layers that need your attention. Check out the horizOn docs to see what ships out of the box.


Source: 1.1.1.1 now supports post-quantum DNSSEC, all 2,420 bytes of it