XTLS/Xray-core · error

failed to build hosts

Error message

failed to build hosts

What it means

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).

Source

Thrown at infra/conf/dns.go:366

		id := nextPolicyID
		nextPolicyID++
		policyMap[key] = id
		return id
	}

	for _, server := range c.Servers {
		ns, err := server.Build()
		if err != nil {
			return nil, errors.New("failed to build nameserver").Base(err)
		}
		ns.PolicyID = buildPolicyID(server)
		config.NameServer = append(config.NameServer, ns)
	}

	if c.Hosts != nil {
		staticHosts, err := c.Hosts.Build()
		if err != nil {
			return nil, errors.New("failed to build hosts").Base(err)
		}
		config.StaticHosts = append(config.StaticHosts, staticHosts...)
	}
	if c.UseSystemHosts {
		systemHosts, err := readSystemHosts()
		if err != nil {
			return nil, errors.New("failed to read system hosts").Base(err)
		}
		config.StaticHosts = append(config.StaticHosts, systemHosts...)
	}

	return config, nil
}

func resolveQueryStrategy(queryStrategy string) dns.QueryStrategy {
	switch strings.ToLower(queryStrategy) {
	case "useip", "use_ip", "use-ip":
		return dns.QueryStrategy_USE_IP

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Read the chained base error to see the rejected key
  2. Use plain fully-qualified domain names as hosts keys
  3. Remove wildcard or special-character keys from dns.hosts

Example fix

// before
"hosts": {"*.example.com": "1.2.3.4"}

// after
"hosts": {"example.com": "1.2.3.4"}
Defensive patterns

Strategy: try-catch

Validate before calling

for host := range dnsCfg.Hosts.Hosts {
    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) {
        return fmt.Errorf("hosts key %q is not a valid full domain", host)
    }
}

Try / catch

if _, err := dnsConf.Build(); err != nil {
    if strings.Contains(err.Error(), "failed to build hosts") {
        root := err
        for errors.Unwrap(root) != nil {
            root = errors.Unwrap(root)
        }
        return fmt.Errorf("a dns.hosts key was rejected: %v", root)
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/a842bb22ab3969f0. Report an issue: GitHub.