XTLS/Xray-core · error
UplinkDataPlacement can be only in packet-up mode
Error message
UplinkDataPlacement can be only in packet-up mode
What it means
SplitHTTPConfig.Build() restricts uplink data placement to the request body except in packet-up mode, at transport_method.go:362-369. Placing raw packet data in a cookie or header is only meaningful when each uplink HTTP request carries one packet ("packet-up" mode); in "auto"/"stream-up"/"stream-one" the data is a continuous stream and must go in the body (PlacementAuto/PlacementBody). The message interpolates c.UplinkDataPlacement (appears empty when the constant's string value is blank in the rendered message).
Source
Thrown at infra/conf/transport_method.go:368
default:
return nil, errors.New("unsupported padding placement: " + c.XPaddingPlacement)
}
switch c.XPaddingMethod {
case "":
c.XPaddingMethod = "repeat-x"
case "repeat-x", "tokenish":
default:
return nil, errors.New("unsupported padding method: " + c.XPaddingMethod)
}
switch c.UplinkDataPlacement {
case "":
c.UplinkDataPlacement = splithttp.PlacementAuto
case splithttp.PlacementAuto, splithttp.PlacementBody:
case splithttp.PlacementCookie, splithttp.PlacementHeader:
if c.Mode != "packet-up" {
return nil, errors.New("UplinkDataPlacement can be " + c.UplinkDataPlacement + " only in packet-up mode")
}
default:
return nil, errors.New("unsupported uplink data placement: " + c.UplinkDataPlacement)
}
if c.UplinkHTTPMethod == "" {
c.UplinkHTTPMethod = "POST"
}
c.UplinkHTTPMethod = strings.ToUpper(c.UplinkHTTPMethod)
if c.UplinkHTTPMethod == "GET" && c.Mode != "packet-up" {
return nil, errors.New("uplinkHTTPMethod can be GET only in packet-up mode")
}
switch c.SessionIDPlacement {
case "":
c.SessionIDPlacement = "path"
case "path", "cookie", "header", "query":View on GitHub (pinned to 7d214f8b09)
Solutions
- Set "mode": "packet-up" when using "uplinkDataPlacement": "cookie" or "header"
- Or change placement to "auto"/"body" for stream modes
- Keep client and server mode/placement choices in sync — both ends must agree
Example fix
// before "mode": "auto", "uplinkDataPlacement": "header" // after "mode": "packet-up", "uplinkDataPlacement": "header"
Defensive patterns
Strategy: validation
Validate before calling
// Go: cookie/header uplink placement requires packet-up mode
mode := cfg.Mode
if mode == "" {
mode = "auto"
}
if cfg.UplinkDataPlacement == "cookie" || cfg.UplinkDataPlacement == "header" {
if mode != "packet-up" {
return errors.New("set mode=packet-up or use auto/body placement")
}
} Prevention
- Pair cookie/header uplinkDataPlacement with packet-up mode
- Default mode is auto — explicitly set packet-up when using these placements
When it happens
Trigger: "uplinkDataPlacement": "cookie" or "header" together with "mode": "auto" (or "stream-up"/"stream-one", or mode omitted — default is auto). Placement "auto" and "body" never trigger it.
Common situations: Copying a tuned packet-up client config but changing/removing the mode line; server-side config reuse where mode was not updated in sync; mixing examples from different guides.
Related errors
- unsupported mode:
- unsupported uplink data placement:
- uplinkHTTPMethod can be GET only in packet-up mode
- Can not use "downloadSettings" in "stream-one" mode.
- Failed to unmarshal "extra".
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/466c5366c50ffb0c.
Report an issue: GitHub.