txthinking/brook · error
quic max datagram size is 1197
Error message
quic max datagram size is 1197
What it means
QUICClient.UDPHandle enforces a maximum QUIC datagram payload size of 1197 bytes. The check 12+4+1+len(DstAddr)+2+len(Data)+16 counts the QUIC packet header, the SOCKS address block (ATyp + address + port), the datagram payload, and the AEAD overhead (16 bytes). If the client's datagram (address + payload) would exceed this QUIC datagram ceiling, the relay is rejected before any packet is sent.
Source
Thrown at quicclient.go:146
}
if err := sc.Exchange(c); err != nil {
return nil
}
return nil
}
if r.Cmd == socks5.CmdUDP {
_, err := r.UDP(c, x.Server.ServerAddr)
if err != nil {
return err
}
return nil
}
return socks5.ErrUnsupportCmd
}
func (x *QUICClient) UDPHandle(s *socks5.Server, addr *net.UDPAddr, d *socks5.Datagram) error {
if 12+4+1+len(d.DstAddr)+2+len(d.Data)+16 > 1197 {
return errors.New("quic max datagram size is 1197")
}
dstb := append(append([]byte{d.Atyp}, d.DstAddr...), d.DstPort...)
conn, err := x.PacketConnFactory.Handle(addr, dstb, d.Data, func(b []byte) (int, error) {
d.Data = b
return s.UDPConn.WriteToUDP(d.Bytes(), addr)
}, x.UDPTimeout)
if err != nil {
return err
}
if conn == nil {
return nil
}
defer conn.Close()
sa := x.ServerAddress
if sa == "" {
sa = x.ServerHost
}
rc, err := QUICDialUDP(addr.String(), d.Address(), sa, x.TLSConfig, x.UDPTimeout)View on GitHub (pinned to 5cd13ef3b1)
Solutions
- Reduce the outgoing UDP datagram payload size to fit: keep len(DstAddr) + len(Data) below 1197 - 34 bytes (about 1163 bytes minus address bytes).
- For DNS traffic, prefer TCP or DNS-over-HTTPS for responses exceeding the limit, or enable EDNS truncation so resolvers send TC=1 instead of oversized UDP answers.
- If the tunnel must carry large datagrams, switch the transport to a stream-based protocol (e.g. the TCP/TLS client) instead of QUIC datagrams.
Example fix
// before
d.Data = bigPayload // e.g. 1300 bytes
client.UDPHandle(server, addr, d) // panics back with "quic max datagram size is 1197"
// after
const maxQuicDatagram = 1197 - 34 - len(d.DstAddr) // overhead + address
if len(d.Data) > maxQuicDatagram {
d.Data = d.Data[:maxQuicDatagram] // or fragment / use TCP transport
} Defensive patterns
Strategy: validation
Validate before calling
const maxQuicPayload = 1197 - 12 - 4 - 1 - 2 - 16 // 1162 minus address bytes
func fitsQuicDatagram(dstAddr, data []byte) bool {
return 12+4+1+len(dstAddr)+2+len(data)+16 <= 1197
} Try / catch
// Go: inspect the error from UDPHandle
if err := client.UDPHandle(srv, addr, d); err != nil && strings.Contains(err.Error(), "max datagram size") {
// fall back to TCP transport or fragment the payload
} Prevention
- Cap outbound UDP payloads through QUIC at ~1160 bytes minus address length.
- Prefer TCP transport for traffic that can exceed the QUIC datagram limit (large DNS, video, QUIC-in-QUIC).
- Enable EDNS0 truncation so oversized DNS replies come via TCP.
When it happens
Trigger: Calling QUICClient.UDPHandle (via the socks5 server UDP path) with a Datagram whose DstAddr plus Data length exceeds 1197 - 34 bytes of fixed overhead, i.e. a payload over roughly 1163 bytes minus address length (long IPv6/hostname targets shrink the usable payload further).
Common situations: Clients sending large UDP payloads through the QUIC transport, e.g. DNS responses with large answers, a UDP datagram close to the 1500-byte Ethernet MTU, or apps ignoring QUIC's smaller effective MTU compared to plain UDP forwarding.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- when write to client, quic max datagram size is 1197
- socks5 server requires a clear IP for UDP, only port is not
- no question
- no question
- Expired request
AI-assisted analysis of txthinking/brook@5cd13ef3b1 (2026-09-06).
Data as JSON: /api/errors/1790d4ed7b41afe8.
Report an issue: GitHub.