txthinking/brook · error
dst too long
Error message
dst too long
What it means
NewSimpleStreamClient rejects a destination address whose encoded length exceeds 2048-32-2-4 (2010) bytes, because the fixed 2048-byte handshake buffer must hold the 32-byte password hash, 2-byte length prefix, 4-byte timestamp, and the dst address. dst longer than that would overflow the buffer, so the constructor fails fast.
Source
Thrown at simplestreamclient.go:41
"github.com/txthinking/socks5"
"github.com/txthinking/x"
)
type SimpleStreamClient struct {
Server net.Conn
Timeout int
RB []byte
WB []byte
network string
src string
dst string
}
func NewSimpleStreamClient(network string, password []byte, src string, server net.Conn, timeout int, dst []byte) (Exchanger, error) {
c := &SimpleStreamClient{network: network, Server: server, Timeout: timeout, src: src, dst: socks5.ToAddress(dst[0], dst[1:len(dst)-2], dst[len(dst)-2:])}
if len(dst) > 2048-32-2-4 {
return nil, errors.New("dst too long")
}
b := x.BP2048.Get().([]byte)
binary.BigEndian.PutUint16(b[32:32+2], uint16(4+len(dst)))
i := time.Now().Unix()
if c.network == "tcp" && i%2 != 0 {
i += 1
}
if c.network == "udp" && i%2 != 1 {
i += 1
}
binary.BigEndian.PutUint32(b[32+2:32+2+4], uint32(i))
copy(b[:32], password)
copy(b[32+2+4:], dst)
if _, err := server.Write(b[:32+2+4+len(dst)]); err != nil {
x.BP2048.Put(b)
return nil, err
}
if c.network == "tcp" {View on GitHub (pinned to 5cd13ef3b1)
Solutions
- Shorten the destination hostname or use an IP address literal instead of a very long name
- Validate/limit the dst address length before constructing the client and reject oversized requests earlier
- Check that dst bytes are a well-formed SOCKS5 address (ATYP + addr + port); a malformed slice with trailing garbage inflates the length
- If legitimate long destinations are required, use a protocol variant with a larger buffer
Example fix
// before
if len(dst) > 2048 { /* no check, just send */ }
// after
if len(dst) > 2048-32-2-4 {
return nil, errors.New("dst too long")
}
cl, err := NewSimpleStreamClient(network, password, src, server, timeout, dst) Defensive patterns
Strategy: validation
Validate before calling
if len(dst) > 2048-32-2-4 {
return fmt.Errorf("destination address too long: %d bytes (max %d)", len(dst), 2048-32-2-4)
} Try / catch
cl, err := NewSimpleStreamClient(network, password, src, server, timeout, dst)
if err != nil {
if err.Error() == "dst too long" {
return nil, fmt.Errorf("cannot proxy to %q: address exceeds protocol limit", dst)
}
return nil, err
} Prevention
- Validate SOCKS5 address encoding before constructing the client
- Prefer IP literals or reasonably short hostnames
- Reject oversized destinations at the proxy front-end before dialing upstream
When it happens
Trigger: Calling NewSimpleStreamClient (directly or via CreateExchanger/TCPHandle/UDPHandle) with a dst byte slice that, after socks5.ToAddress encoding, is longer than 2010 bytes — typically a very long hostname or an oversized crafted address blob.
Common situations: Proxying to hosts with abnormally long DNS names (near the 253-char DNS limit times overhead is still fine — real cases come from malformed/corrupt upstream address bytes or hostile clients sending giant address fields).
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
- socks5 server requires a clear IP for UDP, only port is not
- Invalid dial with IP
- no question
- no question
- This is ipv4
AI-assisted analysis of txthinking/brook@5cd13ef3b1 (2026-09-06).
Data as JSON: /api/errors/1c998550aaa44dd3.
Report an issue: GitHub.