fatedier/frp · error
truncated zone
Error message
truncated zone
What it means
While decoding a v2 binary-encoded UDP address (EncodeUDPPacketBinary format), the zone length byte claims more bytes than remain in the buffer. Every v2 binary UDP address carries a 1-byte zone length even for IPv4; if the packet was truncated mid-address, decoding fails with this error. It signals stream corruption, truncation, or a non-UDP frame being fed to the binary decoder.
Source
Thrown at pkg/msg/udp_binary.go:208
switch family {
case 4:
ipLen = net.IPv4len
case 6:
ipLen = net.IPv6len
default:
return nil, offset, fmt.Errorf("unknown address family %d", family)
}
if len(body)-offset < ipLen+3 {
return nil, offset, fmt.Errorf("truncated address")
}
ip := append(net.IP(nil), body[offset:offset+ipLen]...)
offset += ipLen
port := binary.BigEndian.Uint16(body[offset : offset+2])
offset += 2
zoneLen := int(body[offset])
offset++
if len(body)-offset < zoneLen {
return nil, offset, fmt.Errorf("truncated zone")
}
zoneBytes := body[offset : offset+zoneLen]
if family == 4 && zoneLen != 0 {
return nil, offset, fmt.Errorf("IPv4 zone is forbidden")
}
if !utf8.Valid(zoneBytes) {
return nil, offset, fmt.Errorf("zone is not valid UTF-8")
}
offset += zoneLen
return &net.UDPAddr{IP: ip, Port: int(port), Zone: string(zoneBytes)}, offset, nil
}
type V2BinaryUDPPacketReadWriter struct {
conn *wire.Conn
}
func NewV2BinaryUDPPacketReadWriter(rw io.ReadWriter) *V2BinaryUDPPacketReadWriter {
return &V2BinaryUDPPacketReadWriter{conn: wire.NewConn(rw)}View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Treat this as fatal for the connection: close and re-establish the work connection — the stream is desynchronized, so subsequent frames cannot be trusted.
- Confirm frpc and frps run the same frp version so the binary codec layout matches.
- Remove any intermediary that mangles the TCP stream (some LBs with frame inspection).
- If writing a custom encoder, ensure the zone length byte is always written (0 for IPv4).
Defensive patterns
Strategy: try-catch
Try / catch
if _, err := rw.ReadMsg(); err != nil {
if strings.Contains(err.Error(), "truncated") {
// stream is desynchronized or corrupted: close the work connection and let frp re-establish it
conn.Close()
return err
}
} Prevention
- Never continue reading a connection after a truncation error — framing is unrecoverable.
- Keep frpc and frps on the same release so binary layouts match.
- Avoid intermediaries that modify the TCP stream between peers.
When it happens
Trigger: DecodeUDPPacketBinary (via V2BinaryUDPPacketReadWriter.ReadMsg) receives a payload where the address section ends before family+IP+port+zoneLen fully fit — e.g. a frame cut short by a read timeout, a man-in-the-middle/garbage stream, or a peer using an incompatible binary layout.
Common situations: A TCP connection carrying work-conn UDP traffic is interrupted mid-frame; frpc and frps versions disagree on the binary UDP packet layout; a load balancer or proxy truncates long-lived frames; test harness sends hand-crafted frames with wrong offsets.
Related errors
- IPv4 zone is forbidden
- zone is not valid UTF-8
- received JSON UDP packet after binary codec negotiation
- unexpected frame type %d, want %d
- message frame payload too short
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/5b4881756a35baea.
Report an issue: GitHub.