fatedier/frp · error
selected UDP packet codec was not advertised by client: %s
Error message
selected UDP packet codec was not advertised by client: %s
What it means
Thrown by ValidateServerHelloForClient when the ServerHello selects UDP packet codec "binary" but the client never advertised that codec in ClientHello.Capabilities.Message.UDPPacketCodecs. This guards against a server unilaterally enabling a feature the client did not offer, which would break the client's ability to decode UDP packets.
Source
Thrown at pkg/proto/wire/crypto.go:102
return fmt.Errorf("invalid crypto client random length %d, want %d", len(c.ClientRandom), CryptoRandomSize)
}
if _, ok := SelectAEADAlgorithm(c.Algorithms); !ok {
return fmt.Errorf("no supported crypto algorithm")
}
return nil
}
func ValidateServerHelloForClient(clientHello ClientHello, serverHello ServerHello) error {
if serverHello.Selected.Message.Codec != MessageCodecJSON {
return fmt.Errorf("unsupported selected message codec: %s", serverHello.Selected.Message.Codec)
}
udpPacketCodec := serverHello.Selected.Message.UDPPacketCodec
if udpPacketCodec != "" {
if udpPacketCodec != UDPPacketCodecBinary {
return fmt.Errorf("unsupported selected UDP packet codec: %s", udpPacketCodec)
}
if !Supports(clientHello.Capabilities.Message.UDPPacketCodecs, udpPacketCodec) {
return fmt.Errorf("selected UDP packet codec was not advertised by client: %s", udpPacketCodec)
}
}
cryptoSelection := serverHello.Selected.Crypto
if !IsSupportedAEADAlgorithm(cryptoSelection.Algorithm) {
return fmt.Errorf("unknown selected crypto algorithm: %s", cryptoSelection.Algorithm)
}
if !Supports(clientHello.Capabilities.Crypto.Algorithms, cryptoSelection.Algorithm) {
return fmt.Errorf("selected crypto algorithm was not advertised by client: %s", cryptoSelection.Algorithm)
}
if len(cryptoSelection.ServerRandom) != CryptoRandomSize {
return fmt.Errorf("invalid crypto server random length %d, want %d", len(cryptoSelection.ServerRandom), CryptoRandomSize)
}
return nil
}
func selectUDPPacketCodec(codecs []string) string {
if Supports(codecs, UDPPacketCodecBinary) {
return UDPPacketCodecBinaryView on GitHub (pinned to 6c8a8d0a97)
Solutions
- On the client, include wire.UDPPacketCodecBinary in ClientHello.Capabilities.Message.UDPPacketCodecs when binary UDP encoding is acceptable.
- On the server, derive the selection with selectUDPPacketCodec(clientHello.Capabilities.Message.UDPPacketCodecs) instead of hardcoding it.
- In tests, generate the server hello from the same client hello object that is sent.
Example fix
// before (server) selected.UDPPacketCodec = wire.UDPPacketCodecBinary // hardcoded // after selected.UDPPacketCodec = selectUDPPacketCodec(clientHello.Capabilities.Message.UDPPacketCodecs)
Defensive patterns
Strategy: validation
Validate before calling
// client side: advertise binary support if you can handle it
hello.Capabilities.Message.UDPPacketCodecs = append(
hello.Capabilities.Message.UDPPacketCodecs, wire.UDPPacketCodecBinary)
// server side: only echo what the client offered
if !wire.Supports(clientHello.Capabilities.Message.UDPPacketCodecs, wire.UDPPacketCodecBinary) {
selected.UDPPacketCodec = ""
} Prevention
- Derive every server selection from the client's advertised capability lists.
- In e2e tests, generate the server hello from the exact client hello struct that was serialized.
When it happens
Trigger: Client sends ClientHello with UDPPacketCodecs empty (or lacking "binary"), and the server responds with Selected.Message.UDPPacketCodec = "binary". Validation via Supports(clientHello.Capabilities.Message.UDPPacketCodecs, udpPacketCodec) fails.
Common situations: A server bug that ignores the client's advertised capabilities; a custom client that wants to opt out of the binary UDP codec but talks to a stock server that assumes support; mismatched test hello fixtures where the client hello and server hello are built independently.
Related errors
- unsupported selected UDP packet codec: %s
- selected crypto algorithm was not advertised by client: %s
- serverHello.Error
- wait detect message error: %v
- wait detect message timeout
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/58e60b5ec63b6e42.
Report an issue: GitHub.