{"record":{"id":"a5e0bd6fd42cd15b","repo":"XTLS/Xray-core","slug":"empty-servernames","errorCode":null,"errorMessage":"empty \"serverNames\"","messagePattern":"empty \"serverNames\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_security.go","lineNumber":95,"sourceCode":"\t\t\t\t\ts = string(fullAddr)\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tif _, err = strconv.Atoi(s); err == nil {\n\t\t\t\t\ts = \"localhost:\" + s\n\t\t\t\t}\n\t\t\t\tif _, _, err = net.SplitHostPort(s); err == nil {\n\t\t\t\t\tc.Type = \"tcp\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif c.Type == \"\" {\n\t\t\treturn nil, errors.New(`please fill in a valid value for \"target\"`)\n\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)","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_security.go#L77-L113","documentation":"Thrown by the REALITY builder when the serverNames array is empty. REALITY must know which SNI values to intercept and serve; with no server names the TLS handshake cannot be matched, so the config is rejected.","triggerScenarios":"Omitting serverNames from realitySettings, or providing \"serverNames\": [].","commonSituations":"Migration from常规 TLS configs where serverName was optional client-side; on the server side for REALITY it is mandatory.","solutions":["Add at least one SNI matching your target site, e.g. \"serverNames\": [\"www.microsoft.com\"].","Make sure the SNI is consistent with the target/dest site so the masquerade is credible."],"exampleFix":"// before\n\"realitySettings\": { \"target\": \"www.microsoft.com:443\" }\n// after\n\"realitySettings\": { \"target\": \"www.microsoft.com:443\", \"serverNames\": [\"www.microsoft.com\"] }","handlingStrategy":"validation","validationCode":"if len(reality.ServerNames) == 0 {\n    return errors.New(\"reality requires at least one serverName\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Require serverNames in any REALITY config schema/template.","Keep serverNames aligned with the target site's real SNI."],"tags":["config","reality","sni","validation","go"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}