txthinking/brook · error

packet too long

Error message

packet too long

What it means

Exchange reads a 2-byte big-endian length prefix for a UDP relay packet and rejects the packet if the length exceeds 65507-2 bytes, the theoretical maximum UDP datagram payload. This guards the fixed read buffer s.RB against oversized/invalid length prefixes. A corrupt or malicious stream can set the prefix to a value that cannot be a valid UDP datagram.

Source

Thrown at simplestreamserver.go:146

				return nil
			}
		}
		if s.network == "tcp" {
			l, err := s.Client.Read(s.RB)
			if err != nil {
				return nil
			}
			if _, err := remote.Write(s.RB[:l]); err != nil {
				return nil
			}
		}
		if s.network == "udp" {
			if _, err := io.ReadFull(s.Client, s.RB[:2]); err != nil {
				return nil
			}
			l := int(binary.BigEndian.Uint16(s.RB[:2]))
			if l > 65507-2 {
				return errors.New("packet too long")
			}
			if _, err := io.ReadFull(s.Client, s.RB[2:2+l]); err != nil {
				return nil
			}
			if _, err := remote.Write(s.RB[2 : 2+l]); err != nil {
				return nil
			}
		}
	}
	return nil
}

func (s *SimpleStreamServer) Network() string {
	return s.network
}

func (s *SimpleStreamServer) Src() string {
	return s.src

View on GitHub (pinned to 5cd13ef3b1)

Solutions

  1. Verify the client frames each UDP payload with a 2-byte big-endian length prefix before sending
  2. Check that the declared length includes/excludes the prefix consistently on both ends (server expects payload <= 65505)
  3. Resynchronize or recreate the connection once the stream is desynchronized - the framing cannot recover mid-stream
  4. Cap the datagram size on the client side to 65507 bytes total as required by UDP

Example fix

// before: client sends raw datagram
conn.Write(payload)

// after: frame with 2-byte big-endian length
buf := make([]byte, 2+len(payload))
binary.BigEndian.PutUint16(buf[:2], uint16(len(payload)))
copy(buf[2:], payload)
conn.Write(buf)
Defensive patterns

Strategy: validation

Validate before calling

func validUdpFrame(prefix []byte, payloadLen int) bool {
	l := int(binary.BigEndian.Uint16(prefix[:2]))
	return l > 0 && l <= 65505 && payloadLen == l
}

Prevention

When it happens

Trigger: Calling Exchange on a UDP-mode stream when the first 2 bytes read from the client decode (via binary.BigEndian.Uint16) to a length > 65505; this happens when the peer sends malformed framed data or the stream is desynchronized.

Common situations: A non-conforming client writes raw bytes without the 2-byte length framing; a middlebox corrupts the stream; a client implementation uses a wrong byte order or includes extra header bytes in the length.

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


AI-assisted analysis of txthinking/brook@5cd13ef3b1 (2026-09-06). Data as JSON: /api/errors/72f93d833c8911f6. Report an issue: GitHub.