fatedier/frp · error

unsupported UDP packet codec %q

Error message

unsupported UDP packet codec %q

What it means

NewUDPPacketReadWriter rejects a udpPacketCodec string that is neither empty nor "binary" (wire.UDPPacketCodecBinary). Only two codec states exist in the v2 branch: default JSON packets or the binary codec; anything else is a configuration typo or a value from a different frp version.

Source

Thrown at pkg/msg/udp_binary.go:333

}

// NewUDPPacketReadWriter selects the negotiated packet codec without changing
// the framing or codecs used by non-UDP messages on the work connection.
func NewUDPPacketReadWriter(rw io.ReadWriter, wireProtocol, udpPacketCodec string) (ReadWriter, error) {
	switch wireProtocol {
	case "", wire.ProtocolV1:
		if udpPacketCodec != "" {
			return nil, fmt.Errorf("UDP packet codec %q requires wire protocol v2", udpPacketCodec)
		}
		return NewV1ReadWriter(rw), nil
	case wire.ProtocolV2:
		switch udpPacketCodec {
		case "":
			return NewV2ReadWriter(rw), nil
		case wire.UDPPacketCodecBinary:
			return NewV2BinaryUDPPacketReadWriter(rw), nil
		default:
			return nil, fmt.Errorf("unsupported UDP packet codec %q", udpPacketCodec)
		}
	default:
		return nil, fmt.Errorf("unsupported wire protocol %q", wireProtocol)
	}
}

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Use only "" (default JSON) or "binary" for udpPacketCodec with wire protocol v2.
  2. Validate user-supplied codec strings against wire.UDPPacketCodecBinary before constructing the read writer.
  3. Check the exact constant: wire.UDPPacketCodecBinary.

Example fix

// before
rw, err := msg.NewUDPPacketReadWriter(conn, wire.ProtocolV2, "bin")

// after
rw, err := msg.NewUDPPacketReadWriter(conn, wire.ProtocolV2, wire.UDPPacketCodecBinary)
Defensive patterns

Strategy: validation

Validate before calling

switch udpPacketCodec {
case "", wire.UDPPacketCodecBinary:
default:
	return fmt.Errorf("unsupported UDP packet codec %q", udpPacketCodec)
}

Type guard

func isSupportedUDPPacketCodec(c string) bool {
	return c == "" || c == wire.UDPPacketCodecBinary
}

Prevention

When it happens

Trigger: Calling NewUDPPacketReadWriter(rw, wire.ProtocolV2, "bin"), "msgpack", "legacy", or any unrecognized string; typically from hand-written config or a config field populated by user input without validation.

Common situations: Typo in udpPacketCodec config; docs/examples from another version naming a codec that this release does not implement; dynamic config generation interpolating an unvalidated value.

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/56e3b91689b2553f. Report an issue: GitHub.