XTLS/Xray-core · error

unknown udp mode

Error message

unknown udp mode

What it means

HeaderCustomUDP.Build (infra/conf/transport_finalmask.go:514) validates the UDP mask's "mode" against an allow-list: "" (default), "prefix" (prepend custom data to each datagram), and "standalone" (send custom data as its own datagrams). Any other string returns "unknown udp mode".

Source

Thrown at infra/conf/transport_finalmask.go:514

	}
	return &custom.ExprArg{
		Value: &custom.ExprArg_Expr{
			Expr: parsedExpr,
		},
	}, nil
}

type HeaderCustomUDP struct {
	Mode   string    `json:"mode"`
	Client []UDPItem `json:"client"`
	Server []UDPItem `json:"server"`
}

func (c *HeaderCustomUDP) Build() (proto.Message, error) {
	switch c.Mode {
	case "", "prefix", "standalone":
	default:
		return nil, errors.New("unknown udp mode")
	}

	for _, item := range c.Client {
		if err := validateCustomItemSpec(item.Capture, item.Packet, item.Rand, item.Reuse, item.Transform); err != nil {
			return nil, err
		}
	}
	for _, item := range c.Server {
		if err := validateCustomItemSpec(item.Capture, item.Packet, item.Rand, item.Reuse, item.Transform); err != nil {
			return nil, err
		}
	}

	client := make([]*custom.UDPItem, 0, len(c.Client))
	for _, item := range c.Client {
		if item.RandRange == nil {
			item.RandRange = &Int32Range{From: 0, To: 255}
		}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Set mode to "prefix" or "standalone", or omit it entirely
  2. Match case exactly; the switch is case-sensitive
  3. Re-check the udpmask settings docs for the header-custom type

Example fix

// before
"mode": "prepend"
// after
"mode": "prefix"
Defensive patterns

Strategy: validation

Validate before calling

const MODES = new Set(['', 'prefix', 'standalone']);
if (!MODES.has(cfg.mode ?? '')) throw new Error(`unknown udp mode: ${cfg.mode} (use prefix/standalone or omit)`);

Type guard

const isUdpMode = (m: string) => ['', 'prefix', 'standalone'].includes(m);

Prevention

When it happens

Trigger: "mode":"suffix", "mode":"PREFIX" (case-sensitive switch — not lowered), "mode":"prepend". An omitted mode is valid (empty string).

Common situations: Guessing mode names instead of consulting the vocabulary; copying TCP header-custom settings where mode doesn't exist; version skew where a fork added modes Xray-core doesn't know.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/834e2c9986f2c04f. Report an issue: GitHub.