{"record":{"id":"d77836f329bfd94b","repo":"XTLS/Xray-core","slug":"invalid-redirect-port","errorCode":null,"errorMessage":"invalid redirect port: {}","messagePattern":"invalid redirect port: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/freedom.go","lineNumber":168,"sourceCode":"\t\tfor _, n := range c.Noises {\n\t\t\tNConfig, err := ParseNoise(n)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tconfig.Noises = append(config.Noises, NConfig)\n\t\t}\n\t}\n\n\tconfig.UserLevel = c.UserLevel\n\n\tif len(c.Redirect) > 0 {\n\t\thost, portStr, err := net.SplitHostPort(c.Redirect)\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"invalid redirect address: \", c.Redirect, \": \", err).Base(err)\n\t\t}\n\t\tport, err := xnet.PortFromString(portStr)\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"invalid redirect port: \", c.Redirect, \": \", err).Base(err)\n\t\t}\n\t\tconfig.DestinationOverride = &freedom.DestinationOverride{\n\t\t\tServer: &protocol.ServerEndpoint{\n\t\t\t\tPort: uint32(port),\n\t\t\t},\n\t\t}\n\n\t\tif len(host) > 0 {\n\t\t\tconfig.DestinationOverride.Server.Address = xnet.NewIPOrDomain(xnet.ParseAddress(host))\n\t\t}\n\t}\n\n\tif c.ProxyProtocol > 0 && c.ProxyProtocol <= 2 {\n\t\tconfig.ProxyProtocol = c.ProxyProtocol\n\t}\n\n\tfor _, r := range c.FinalRules {\n\t\trule, err := r.Build()","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/freedom.go#L150-L186","documentation":"Thrown when the freedom outbound's 'redirect' address splits into host:port but the port substring is not a valid port per xnet.PortFromString. This catches out-of-range ports (>65535), non-numeric ports, and empty port strings after the SplitHostPort stage has already succeeded.","triggerScenarios":"\"redirect\": \"example.com:70000\" (exceeds 65535), \"redirect\": \"example.com:https\" (service name not accepted), \"redirect\": \"example.com:\" (empty port). The chained base error identifies the port parse failure.","commonSituations":"Typos in port numbers; expecting symbolic port names to resolve; trailing colon after deleting a port.","solutions":["Use a numeric port between 1 and 65535, e.g. \"example.com:443\".","Replace service-name ports (\"https\", \"http\") with their numbers.","If only redirecting traffic regardless of port, keep an explicit valid port — the field requires one."],"exampleFix":"// before\n\"redirect\": \"example.com:70000\"\n\n// after\n\"redirect\": \"example.com:443\"","handlingStrategy":"validation","validationCode":"_, portStr, _ := net.SplitHostPort(redirect)\nif p, err := strconv.ParseUint(portStr, 10, 16); err != nil || p == 0 {\n    return fmt.Errorf(\"redirect port %q must be 1-65535\", portStr)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use numeric ports only; no service names like \"https\".","Keep ports in 1-65535 when generating configs."],"tags":["go","xray","freedom","outbound","port","config","validation"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}