{"record":{"id":"5b2e08abf7e338ea","repo":"XTLS/Xray-core","slug":"scmaxeachpostbytes-should-be-bigger-than-0","errorCode":null,"errorMessage":"`scMaxEachPostBytes` should be bigger than 0","messagePattern":"`scMaxEachPostBytes` should be bigger than 0","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"transport/internet/splithttp/dialer.go","lineNumber":487,"sourceCode":"\t\t\treturn nil, err\n\t\t}\n\t}\n\tif mode == \"stream-up\" {\n\t\tif xmuxClient != nil {\n\t\t\txmuxClient.LeftRequests.Add(-1)\n\t\t}\n\t\t_, _, _, err = httpClient.OpenStream(ctx, requestURL.String(), sessionId, reader, true)\n\t\tif err != nil { // browser dialer only\n\t\t\treturn nil, err\n\t\t}\n\t\treturn stat.Connection(&conn), nil\n\t}\n\n\tscMaxEachPostBytes := transportConfiguration.GetNormalizedScMaxEachPostBytes()\n\tscMinPostsIntervalMs := transportConfiguration.GetNormalizedScMinPostsIntervalMs()\n\n\tif scMaxEachPostBytes.From <= 0 {\n\t\tpanic(\"`scMaxEachPostBytes` should be bigger than 0\")\n\t}\n\n\tmaxUploadSize := scMaxEachPostBytes.rand()\n\t// WithSizeLimit(0) will still allow single bytes to pass, and a lot of\n\t// code relies on this behavior. Subtract 1 so that together with\n\t// uploadWriter wrapper, exact size limits can be enforced\n\t// uploadPipeReader, uploadPipeWriter := pipe.New(pipe.WithSizeLimit(maxUploadSize - 1))\n\tuploadPipeReader, uploadPipeWriter := pipe.New(pipe.WithSizeLimit(max(0, maxUploadSize-buf.Size)))\n\n\tconn.writer = uploadWriter{\n\t\tuploadPipeWriter,\n\t\tmaxUploadSize,\n\t}\n\n\tgo func() {\n\t\tvar seq int64\n\t\tvar lastWrite time.Time\n","sourceCodeStart":469,"sourceCodeEnd":505,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/transport/internet/splithttp/dialer.go#L469-L505","documentation":"The splithttp dialer panics because GetNormalizedScMaxEachPostBytes().From is <= 0 after normalization. Normalization only substitutes defaults when ScMaxEachPostBytes is nil or To == 0; a RangeConfig explicitly present with From <= 0 (or To set but From unset/negative) reaches this check and kills the process at stream-dial time. scMaxEachPostBytes caps the size of each POST upload chunk in stream-up (XHTTP) mode.","triggerScenarios":"Explicitly setting \"scMaxEachPostBytes\": {\"from\": 0} or {\"to\": N} without a positive \"from\" in the splithttp transport config; negative values; configs generated programmatically that zero the From field while keeping To.","commonSituations":"Hand-written JSON where only \"to\" is set because authors assume from is optional; migrating from configs where the field was a plain integer; tools that emit 0 for unset numeric fields (proto3 default) combined with a non-zero To.","solutions":["Set both bounds positive, e.g. {\"from\": 1000000, \"to\": 2000000}, or remove the scMaxEachPostBytes block entirely to take the built-in defaults.","If you only care about a cap, keep From equal to a sane floor (e.g. 1–2 MB) — From drives the random upload-chunk size lower bound and must be >= 1.","Fix config generators to omit the field rather than emit {from:0,to:0}."],"exampleFix":"// before (config.json splithttp settings)\n\"scMaxEachPostBytes\": { \"to\": 2000000 }\n// after\n\"scMaxEachPostBytes\": { \"from\": 1000000, \"to\": 2000000 }","handlingStrategy":"validation","validationCode":"if c.ScMaxEachPostBytes != nil && (c.ScMaxEachPostBytes.From <= 0 || c.ScMaxEachPostBytes.To < c.ScMaxEachPostBytes.From) {\n    return errors.New(\"scMaxEachPostBytes must satisfy 0 < from <= to\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set both from and to to positive values, or omit scMaxEachPostBytes to use defaults.","Omit the field rather than emitting {from:0,to:0} in generated configs (proto3 zero values).","Check the effective normalized values in a startup log line while debugging upload issues."],"tags":["splithttp","xhttp","panic","config","upload"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}