XTLS/Xray-core · error

failed to read system hosts

Error message

failed to read system hosts

What it means

Wrapper error from dns Config Build in infra/conf/dns.go: readSystemHosts() failed while dns.useSystemHosts is enabled. The function reads the OS hosts file (e.g. /etc/hosts); I/O or parse failures are chained with .Base(err). This is an environment-level failure, not a config syntax problem.

Source

Thrown at infra/conf/dns.go:373

		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
	case "useip4", "useipv4", "use_ip4", "use_ipv4", "use_ip_v4", "use-ip4", "use-ipv4", "use-ip-v4":
		return dns.QueryStrategy_USE_IP4
	case "useip6", "useipv6", "use_ip6", "use_ipv6", "use_ip_v6", "use-ip6", "use-ipv6", "use-ip-v6":
		return dns.QueryStrategy_USE_IP6
	case "usesys", "usesystem", "use_sys", "use_system", "use-sys", "use-system":
		return dns.QueryStrategy_USE_SYS
	default:

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Check the chained base error for the OS-level cause (permission vs not-found)
  2. Ensure /etc/hosts exists and is readable by the Xray process user
  3. Set "useSystemHosts": false if system hosts are not needed

Example fix

// before
"dns": {"useSystemHosts": true}   // in a container lacking /etc/hosts

// after
"dns": {"useSystemHosts": false, "hosts": {"example.com": "1.2.3.4"}}
Defensive patterns

Strategy: try-catch

Validate before calling

if dnsCfg.UseSystemHosts {
    f, err := os.Open(hostsFilePathForOS()) // "/etc/hosts" on unix
    if err != nil {
        return fmt.Errorf("useSystemHosts enabled but hosts file unreadable: %w", err)
    }
    f.Close()
}

Try / catch

if _, err := dnsConf.Build(); err != nil {
    if strings.Contains(err.Error(), "failed to read system hosts") {
        // environment problem: fix permissions/mount or disable the feature
        return errors.New("cannot read the OS hosts file; fix /etc/hosts or set dns.useSystemHosts to false")
    }
    return err
}

Prevention

When it happens

Trigger: "dns": {"useSystemHosts": true} on a system where /etc/hosts is unreadable (permissions), missing, or on Windows where the hosts path is absent/locked by security software.

Common situations: Containers with a broken /etc/hosts mount; minimal Docker images without the file; SELinux/AppArmor denying read; hosts file with exotic encoding causing parse failure.

Related errors


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