{"record":{"id":"fd68e9da4bdc0d74","repo":"XTLS/Xray-core","slug":"invalid-minclientver","errorCode":null,"errorMessage":"invalid \"minClientVer\": ","messagePattern":"invalid \"minClientVer\": ","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_security.go","lineNumber":108,"sourceCode":"\t\t}\n\t\tif c.Xver > 2 {\n\t\t\treturn nil, errors.New(`invalid PROXY protocol version, \"xver\" only accepts 0, 1, 2`)\n\t\t}\n\t\tif len(c.ServerNames) == 0 {\n\t\t\treturn nil, errors.New(`empty \"serverNames\"`)\n\t\t}\n\t\tif c.PrivateKey == \"\" {\n\t\t\treturn nil, errors.New(`empty \"privateKey\"`)\n\t\t}\n\t\tif config.PrivateKey, err = base64.RawURLEncoding.DecodeString(c.PrivateKey); err != nil || len(config.PrivateKey) != 32 {\n\t\t\treturn nil, errors.New(`invalid \"privateKey\": `, c.PrivateKey)\n\t\t}\n\t\tif c.MinClientVer != \"\" {\n\t\t\tconfig.MinClientVer = make([]byte, 3)\n\t\t\tvar u uint64\n\t\t\tfor i, s := range strings.Split(c.MinClientVer, \".\") {\n\t\t\t\tif i == 3 {\n\t\t\t\t\treturn nil, errors.New(`invalid \"minClientVer\": `, c.MinClientVer)\n\t\t\t\t}\n\t\t\t\tif u, err = strconv.ParseUint(s, 10, 8); err != nil {\n\t\t\t\t\treturn nil, errors.New(`\"minClientVer[`, i, `]\" should be less than 256`)\n\t\t\t\t} else {\n\t\t\t\t\tconfig.MinClientVer[i] = byte(u)\n\t\t\t\t}\n\t\t\t}\n\t\t\terrors.LogWarning(context.Background(), `REALITY: Changing \"minClientVer\" will increase the likelihood of your server's IP being blocked by the GFW`)\n\t\t} else {\n\t\t\tconfig.MinClientVer = []byte{26, 3, 27} // change it at your own risk: https://github.com/XTLS/Xray-core/commit/af7eb68028732a8ee3c0e5d6ab2b8a657bb2e770\n\t\t\terrors.LogWarning(context.Background(), `REALITY: The default minimal client version is Xray-core v26.3.27, other clients may be refused to connect`)\n\t\t}\n\t\tif c.MaxClientVer != \"\" {\n\t\t\tconfig.MaxClientVer = make([]byte, 3)\n\t\t\tvar u uint64\n\t\t\tfor i, s := range strings.Split(c.MaxClientVer, \".\") {\n\t\t\t\tif i == 3 {\n\t\t\t\t\treturn nil, errors.New(`invalid \"maxClientVer\": `, c.MaxClientVer)","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_security.go#L90-L126","documentation":"Thrown by the REALITY builder while parsing minClientVer when the dotted version string has a 4th component (index 3 exists). Client versions are limited to exactly three numeric components (major.minor.patch) because they are stored in a fixed 3-byte array.","triggerScenarios":"Setting \"minClientVer\": \"1.8.6.2\" or any four-part version string.","commonSituations":"Copying a four-part version from an About dialog or a release tag suffix.","solutions":["Use a three-part version, e.g. \"1.8.6\".","Prefer omitting minClientVer entirely (defaults to 26.3.27 with a warning) unless you have a specific reason."],"exampleFix":"// before\n\"minClientVer\": \"1.8.6.2\"\n// after\n\"minClientVer\": \"1.8.6\"","handlingStrategy":"validation","validationCode":"func validVerTriple(s string) bool {\n    parts := strings.Split(s, \".\")\n    if len(parts) > 3 { return false }\n    for _, p := range parts {\n        if n, err := strconv.ParseUint(p, 10, 8); err != nil || n > 255 { return false }\n    }\n    return true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Accept only 3-part dotted versions in config UIs.","Omit minClientVer unless you understand the GFW-blocking warning it carries."],"tags":["config","reality","version","validation","go"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}