{"record":{"id":"7b997c258bfbe002","repo":"XTLS/Xray-core","slug":"gecko-invalid-min-max-packet-size","errorCode":null,"errorMessage":"gecko: invalid min/max packet size","messagePattern":"gecko: invalid min/max packet size","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_finalmask.go","lineNumber":638,"sourceCode":"\t\treturn &header.Config{ID: 3}, nil\n\tcase \"wechat\":\n\t\treturn &header.Config{ID: 4}, nil\n\tcase \"wireguard\":\n\t\treturn &header.Config{ID: 5}, nil\n\tdefault:\n\t\treturn nil, errors.New(\"invalid header \", c.Header)\n\t}\n}\n\ntype Salamander struct {\n\tPassword   string     `json:\"password\"`\n\tPacketSize Int32Range `json:\"packetSize\"`\n}\n\nfunc (c *Salamander) Build() (proto.Message, error) {\n\tif c.PacketSize.To > 0 {\n\t\tif c.PacketSize.From <= 0 || c.PacketSize.To > 2048 {\n\t\t\treturn nil, errors.New(\"gecko: invalid min/max packet size\")\n\t\t}\n\t\treturn &salamander.GeckoConfig{\n\t\t\tPassword:      c.Password,\n\t\t\tMinPacketSize: c.PacketSize.From,\n\t\t\tMaxPacketSize: c.PacketSize.To,\n\t\t}, nil\n\t}\n\treturn &salamander.Config{\n\t\tPassword: c.Password,\n\t}, nil\n}\n\ntype Sudoku struct {\n\tPassword string `json:\"password\"`\n\tASCII    string `json:\"ascii\"`\n\n\tCustomTable       string   `json:\"customTable\"`\n\tLegacyCustomTable string   `json:\"custom_table\"`","sourceCodeStart":620,"sourceCodeEnd":656,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_finalmask.go#L620-L656","documentation":"Thrown by Salamander.Build() (a 'gecko' transport config) when a packetSize range is present but invalid: the config requires 0 < from <= to <= 2048. It uses a custom errors.New that concatenates the message with context. The check only applies when PacketSize.To > 0; if To is 0 the range is omitted entirely and the plain gecko Config is emitted.","triggerScenarios":"Setting json packetSize like {\"from\": 0, \"to\": 1024} (From <= 0) or {\"from\": 1, \"to\": 4096} (To > 2048) on a salamander/gecko outbound triggers it. Any config where To > 0 while From <= 0, or To exceeding the hard 2048 ceiling, fails at config-build time.","commonSituations":"Copy-pasting MTU-like values (e.g. 1500 or 9000) from other transports into packetSize; setting only the max and leaving min at 0; confusing the 2048 hard limit with a larger L1/L2 packet size.","solutions":["Set packetSize.From to a positive value (e.g. 1) whenever To is set.","Cap packetSize.To at 2048 or below.","If you do not need a packet-size range, omit packetSize (or set To to 0) so the plain gecko Config is built."],"exampleFix":"// before\n\"packetSize\": { \"from\": 0, \"to\": 1500 }\n// after\n\"packetSize\": { \"from\": 1, \"to\": 1024 }","handlingStrategy":"validation","validationCode":"func validPacketSize(from, to int32) bool {\n\tif to <= 0 {\n\t\treturn true // range omitted\n\t}\n\treturn from > 0 && to <= 2048 && from <= to\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat 2048 as a hard ceiling when generating salamander packet sizes.","Always emit both from and to together, never a bare max with min=0.","Run JSON config through a JSON-schema or pre-flight validator before loading."],"tags":["go","xray","config","validation","transport"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}