{"record":{"id":"6560506a715259fa","repo":"XTLS/Xray-core","slug":"sessionidtable-or-sessionidlength-is-too-small","errorCode":null,"errorMessage":"sessionIDTable or sessionIDLength is too small","messagePattern":"sessionIDTable or sessionIDLength is too small","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_method.go","lineNumber":415,"sourceCode":"\t}\n\n\tif c.SessionIDPlacement != \"path\" && c.SessionIDKey == \"\" {\n\t\tswitch c.SessionIDPlacement {\n\t\tcase \"cookie\", \"query\":\n\t\t\tc.SessionIDKey = \"x_session\"\n\t\tcase \"header\":\n\t\t\tc.SessionIDKey = \"X-Session\"\n\t\t}\n\t}\n\n\tif c.SessionIDTable != \"\" {\n\t\tif predefined, ok := splithttp.PredefinedTable[c.SessionIDTable]; ok {\n\t\t\tc.SessionIDTable = predefined\n\t\t}\n\t\troom := roomSize(len(c.SessionIDTable), c.SessionIDLength.From, c.SessionIDLength.To)\n\t\t// 2.1B possiblities should be enough\n\t\tif room.Cmp(big.NewInt(2<<30)) < 0 {\n\t\t\treturn nil, errors.New(\"sessionIDTable or sessionIDLength is too small\")\n\t\t}\n\t\tif c.SessionIDLength.From <= 0 {\n\t\t\treturn nil, errors.New(\"sessionIDLength.from must be greater than 0\")\n\t\t}\n\t\tfor i := 0; i < len(c.SessionIDTable); i++ {\n\t\t\tif c.SessionIDTable[i] >= 0x80 {\n\t\t\t\treturn nil, errors.New(\"sessionIDTable must contain only ASCII characters\")\n\t\t\t}\n\t\t}\n\t}\n\n\tif c.SeqPlacement != \"path\" && c.SeqKey == \"\" {\n\t\tswitch c.SeqPlacement {\n\t\tcase \"cookie\", \"query\":\n\t\t\tc.SeqKey = \"x_seq\"\n\t\tcase \"header\":\n\t\t\tc.SeqKey = \"X-Seq\"\n\t\t}","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_method.go#L397-L433","documentation":"When \"sessionIDTable\" is set, SplitHTTPConfig.Build() resolves predefined tables via splithttp.PredefinedTable, then computes roomSize = sum over k in [from,to] of tableLen^k (transport_method.go:512-521) and requires at least 2^31 (2<<30) possible session IDs (line 414). This error means the table plus the sessionIDLength range yields too little entropy — a small character table and/or a short ID length make session IDs guessable/enumerable.","triggerScenarios":"E.g. sessionIDTable \"0123456789\" (10 chars) with sessionIDLength {from:1,to:1}: room = 10 < 2^31. Or a 2-char custom table with any practical length range; or from/to left at 0/0 (room=0 since the loop at line 516 never runs for min=0? — with min=0,max=0 it computes base^0=1). Any combination whose summed possibilities stay under ~2.1 billion fails.","commonSituations":"Users shortening ID length to make URLs smaller; using tiny custom tables for 'prettier' IDs; setting sessionIDTable but forgetting sessionIDLength so the default zero range yields a tiny room; must pair a long-enough table (or predefined table) with an adequate length range.","solutions":["Set \"sessionIDLength\": {\"from\": N, \"to\": N} large enough: with a 64-char table, from=6 (64^6 ≈ 6.9e10) already passes","Or use a bigger \"sessionIDTable\" string / a predefined table name resolvable in splithttp.PredefinedTable","Rule of thumb: tableLen^from must reach ~2^31, so len(table) >= 2^(31/from)"],"exampleFix":"// before\n\"sessionIDTable\": \"0123456789\", \"sessionIDLength\": { \"from\": 1, \"to\": 2 }\n// after\n\"sessionIDTable\": \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-\", \"sessionIDLength\": { \"from\": 6, \"to\": 8 }","handlingStrategy":"validation","validationCode":"// Go: mirror roomSize() and require >= 2^31 possibilities\nfunc sessionRoomOK(table string, from, to int32) bool {\n\tbase := big.NewInt(int64(len(table)))\n\tsum := new(big.Int)\n\tterm := new(big.Int)\n\tfor k := from; k <= to; k++ {\n\t\tif k < 0 {\n\t\t\tcontinue\n\t\t}\n\t\tterm.Exp(base, big.NewInt(int64(k)), nil)\n\t\tsum.Add(sum, term)\n\t}\n\treturn sum.Cmp(big.NewInt(2<<30)) >= 0\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair sessionIDTable with an explicit sessionIDLength range","Ensure tableLen^from >= ~2.1e9 (e.g. 64-char table with from>=6)","Prefer predefined tables, which are sized to pass"],"tags":["config","splithttp","session","entropy","validation"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}