{"record":{"id":"d14c4fb3856bead5","repo":"XTLS/Xray-core","slug":"uplinkhttpmethod-can-be-get-only-in-packet-up-mode","errorCode":null,"errorMessage":"uplinkHTTPMethod can be GET only in packet-up mode","messagePattern":"uplinkHTTPMethod can be GET only in packet-up mode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_method.go","lineNumber":380,"sourceCode":"\tswitch c.UplinkDataPlacement {\n\tcase \"\":\n\t\tc.UplinkDataPlacement = splithttp.PlacementAuto\n\tcase splithttp.PlacementAuto, splithttp.PlacementBody:\n\tcase splithttp.PlacementCookie, splithttp.PlacementHeader:\n\t\tif c.Mode != \"packet-up\" {\n\t\t\treturn nil, errors.New(\"UplinkDataPlacement can be \" + c.UplinkDataPlacement + \" only in packet-up mode\")\n\t\t}\n\tdefault:\n\t\treturn nil, errors.New(\"unsupported uplink data placement: \" + c.UplinkDataPlacement)\n\t}\n\n\tif c.UplinkHTTPMethod == \"\" {\n\t\tc.UplinkHTTPMethod = \"POST\"\n\t}\n\tc.UplinkHTTPMethod = strings.ToUpper(c.UplinkHTTPMethod)\n\n\tif c.UplinkHTTPMethod == \"GET\" && c.Mode != \"packet-up\" {\n\t\treturn nil, errors.New(\"uplinkHTTPMethod can be GET only in packet-up mode\")\n\t}\n\n\tswitch c.SessionIDPlacement {\n\tcase \"\":\n\t\tc.SessionIDPlacement = \"path\"\n\tcase \"path\", \"cookie\", \"header\", \"query\":\n\tdefault:\n\t\treturn nil, errors.New(\"unsupported session placement: \" + c.SessionIDPlacement)\n\t}\n\n\tswitch c.SeqPlacement {\n\tcase \"\":\n\t\tc.SeqPlacement = \"path\"\n\tcase \"path\", \"cookie\", \"header\", \"query\":\n\tdefault:\n\t\treturn nil, errors.New(\"unsupported seq placement: \" + c.SeqPlacement)\n\t}\n","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_method.go#L362-L398","documentation":"SplitHTTPConfig.Build() uppercases the uplink HTTP method (default \"POST\") and rejects \"GET\" outside packet-up mode at transport_method.go:374-381. GET requests have no body, so uplink data can only be carried in cookies/headers/URL — which is a packet-up concept. In stream modes the uplink body is required, hence POST.","triggerScenarios":"\"uplinkHTTPMethod\": \"get\" or \"GET\" (uppercased at line 377, so any casing matches) combined with mode \"auto\"/\"stream-up\"/\"stream-one\" or mode omitted. Any other method value (PUT, DELETE) is accepted without a mode check.","commonSituations":"Tuning guides recommending GET-based uplink for CDN compatibility without noting the packet-up requirement; switching mode for troubleshooting and forgetting the method constraint.","solutions":["Set \"mode\": \"packet-up\" alongside \"uplinkHTTPMethod\": \"GET\"","Or remove/change uplinkHTTPMethod to \"POST\" for auto/stream modes"],"exampleFix":"// before\n\"mode\": \"stream-up\", \"uplinkHTTPMethod\": \"GET\"\n// after\n\"mode\": \"packet-up\", \"uplinkHTTPMethod\": \"GET\"","handlingStrategy":"validation","validationCode":"// Go: GET uplink only in packet-up\nm := strings.ToUpper(cfg.UplinkHTTPMethod)\nif m == \"\" {\n\tm = \"POST\"\n}\nmode := cfg.Mode\nif mode == \"\" {\n\tmode = \"auto\"\n}\nif m == \"GET\" && mode != \"packet-up\" {\n\treturn errors.New(\"uplinkHTTPMethod GET requires mode packet-up\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["GET uplink implies packet-up — set both or neither","Casing does not matter (uppercased internally) but mode must be exact"],"tags":["config","splithttp","http-method","mode"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}