fatedier/frp · error

unsupported UDP packet codec selection: %s

Error message

unsupported UDP packet codec selection: %s

What it means

With wire protocol v2, RegisterControl only accepts udpPacketCodec values that are empty or equal to the built-in binary codec; anything else is rejected as an unsupported selection. This guards against clients requesting codec names the server cannot negotiate.

Source

Thrown at server/service.go:781

		}(context.Background(), c)
	}
}

func (svr *Service) RegisterControl(
	ctlConn *msg.Conn,
	loginMsg *msg.Login,
	internal bool,
	wireProtocol string,
	udpPacketCodec string,
) (*Control, error) {
	switch wireProtocol {
	case wire.ProtocolV1:
		if udpPacketCodec != "" {
			return nil, fmt.Errorf("UDP packet codec %q requires wire protocol v2", udpPacketCodec)
		}
	case wire.ProtocolV2:
		if udpPacketCodec != "" && udpPacketCodec != wire.UDPPacketCodecBinary {
			return nil, fmt.Errorf("unsupported UDP packet codec selection: %s", udpPacketCodec)
		}
	default:
		return nil, fmt.Errorf("unsupported wire protocol: %s", wireProtocol)
	}
	// If client's RunID is empty, it's a new client, we just create a new controller.
	// Otherwise, we check if there is one controller has the same run id. If so, we release previous controller and start new one.
	var err error
	if loginMsg.RunID == "" {
		loginMsg.RunID, err = util.RandID()
		if err != nil {
			return nil, err
		}
	}
	if err := validation.ValidateRunID(loginMsg.RunID); err != nil {
		return nil, fmt.Errorf("invalid run id: %w", err)
	}

	ctx := netpkg.NewContextFromConn(ctlConn)

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Set udpPacketCodec = "binary" (the only supported value) or leave it empty
  2. Check for whitespace/case errors in the value
  3. Upgrade frps if a newer codec name is genuinely required by your frpc

Example fix

# before
udpPacketCodec = "protobuf"

# after
udpPacketCodec = "binary"
Defensive patterns

Strategy: validation

Validate before calling

if cfg.UDPPacketCodec != "" && cfg.UDPPacketCodec != "binary" {
    return fmt.Errorf("udpPacketCodec must be empty or 'binary', got %q", cfg.UDPPacketCodec)
}

Prevention

When it happens

Trigger: udpPacketCodec set to a misspelled or not-yet-implemented value (e.g. "binary " with whitespace, "protobuf", "text") while on v2; configs from a future/other fork referencing codecs this server lacks.

Common situations: Typos in the codec name; version skew where the client knows a codec the server does not; hand-ported configs.

Related errors


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