{"record":{"id":"a842bb22ab3969f0","repo":"XTLS/Xray-core","slug":"failed-to-build-hosts","errorCode":null,"errorMessage":"failed to build hosts","messagePattern":"failed to build hosts","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/dns.go","lineNumber":366,"sourceCode":"\t\tid := nextPolicyID\n\t\tnextPolicyID++\n\t\tpolicyMap[key] = id\n\t\treturn id\n\t}\n\n\tfor _, server := range c.Servers {\n\t\tns, err := server.Build()\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"failed to build nameserver\").Base(err)\n\t\t}\n\t\tns.PolicyID = buildPolicyID(server)\n\t\tconfig.NameServer = append(config.NameServer, ns)\n\t}\n\n\tif c.Hosts != nil {\n\t\tstaticHosts, err := c.Hosts.Build()\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"failed to build hosts\").Base(err)\n\t\t}\n\t\tconfig.StaticHosts = append(config.StaticHosts, staticHosts...)\n\t}\n\tif c.UseSystemHosts {\n\t\tsystemHosts, err := readSystemHosts()\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"failed to read system hosts\").Base(err)\n\t\t}\n\t\tconfig.StaticHosts = append(config.StaticHosts, systemHosts...)\n\t}\n\n\treturn config, nil\n}\n\nfunc resolveQueryStrategy(queryStrategy string) dns.QueryStrategy {\n\tswitch strings.ToLower(queryStrategy) {\n\tcase \"useip\", \"use_ip\", \"use-ip\":\n\t\treturn dns.QueryStrategy_USE_IP","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/dns.go#L348-L384","documentation":"Wrapper error from dns Config Build in infra/conf/dns.go: HostsWrapper.Build failed while converting dns.hosts entries. Causes include geodata.ParseDomainRule rejecting the hostname used as a hosts key (e.g. it is not a valid full domain) or an entry value that built no mapping; the concrete error is chained via .Base(err).","triggerScenarios":"Hosts keys that are not valid domain names: \"hosts\": {\"*.example.com\": \"1.2.3.4\"} (wildcards may be rejected as Domain_Full), keys with spaces or underscore-prefixed names, or malformed geosite: prefixed keys.","commonSituations":"Trying to wildcard-host entries; copying /etc/hosts lines that contain comments or tabs; recent Xray versions validating hosts keys through geodata rules where older versions accepted anything.","solutions":["Read the chained base error to see the rejected key","Use plain fully-qualified domain names as hosts keys","Remove wildcard or special-character keys from dns.hosts"],"exampleFix":"// before\n\"hosts\": {\"*.example.com\": \"1.2.3.4\"}\n\n// after\n\"hosts\": {\"example.com\": \"1.2.3.4\"}","handlingStrategy":"try-catch","validationCode":"for host := range dnsCfg.Hosts.Hosts {\n    if !regexp.MustCompile(`^(geosite:)?[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)*$`).MatchString(host) {\n        return fmt.Errorf(\"hosts key %q is not a valid full domain\", host)\n    }\n}","typeGuard":null,"tryCatchPattern":"if _, err := dnsConf.Build(); err != nil {\n    if strings.Contains(err.Error(), \"failed to build hosts\") {\n        root := err\n        for errors.Unwrap(root) != nil {\n            root = errors.Unwrap(root)\n        }\n        return fmt.Errorf(\"a dns.hosts key was rejected: %v\", root)\n    }\n    return err\n}","preventionTips":["Use plain FQDNs as hosts keys — no wildcards or special chars","Clean copied /etc/hosts lines of comments and tabs before pasting into dns.hosts"],"tags":["config","dns","hosts","wrapper-error","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}