XTLS/Xray-core · error

Unable to locate a fake DNS Engine

Error message

Unable to locate a fake DNS Engine

What it means

Thrown by FakeDNSServer.QueryIP when the server instance has no fakeDNSEngine attached. The FakeDNS nameserver is only a thin facade: it converts domains to fake IPs by delegating to a dns.FakeDNSEngine feature held elsewhere in the instance. If the engine was never injected (feature not registered or nameserver constructed standalone), every DNS query through it fails immediately.

Source

Thrown at app/dns/nameserver_fakedns.go:30

	fakeDNSEngine dns.FakeDNSEngine
}

func NewFakeDNSServer(fd dns.FakeDNSEngine) *FakeDNSServer {
	return &FakeDNSServer{fakeDNSEngine: fd}
}

func (FakeDNSServer) Name() string {
	return "FakeDNS"
}

// IsDisableCache implements Server.
func (s *FakeDNSServer) IsDisableCache() bool {
	return true
}

func (f *FakeDNSServer) QueryIP(ctx context.Context, domain string, opt dns.IPOption) ([]net.IP, uint32, error) {
	if f.fakeDNSEngine == nil {
		return nil, 0, errors.New("Unable to locate a fake DNS Engine").AtError()
	}

	var ips []net.Address
	if fkr0, ok := f.fakeDNSEngine.(dns.FakeDNSEngineRev0); ok {
		ips = fkr0.GetFakeIPForDomain3(domain, opt.IPv4Enable, opt.IPv6Enable)
	} else {
		ips = f.fakeDNSEngine.GetFakeIPForDomain(domain)
	}

	netIP, err := toNetIP(ips)
	if err != nil {
		return nil, 0, errors.New("Unable to convert IP to net ip").Base(err).AtError()
	}

	errors.LogInfo(ctx, f.Name(), " got answer: ", domain, " -> ", ips)

	if len(netIP) > 0 {
		return netIP, 1, nil // fakeIP ttl is 1

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Ensure the dns.FakeDNSEngine feature is registered and started on the core.Instance before the FakeDNS nameserver is used
  2. If constructing servers manually, inject the engine via the constructor path that sets fakeDNSEngine instead of using the bare server struct
  3. Check startup logs for 'failed to register fake DNS engine' style messages and fix the underlying registration error first

Example fix

// before
server := &dns.FakeDNSServer{} // no engine attached
ips, ttl, err := server.QueryIP(ctx, "example.com", opt) // error

// after
// register the fake DNS feature on the instance so the nameserver
// is created with its engine (see app/dns/fakedns.go):
core.Must(core.RegisterConfig((*fakedns.Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {
    return fakedns.New(ctx, cfg.(*fakedns.Config))
}))
// then create the FakeDNS nameserver through the instance, not standalone
Defensive patterns

Strategy: validation

Validate before calling

// Before using a FakeDNS nameserver, confirm the engine feature is present:
if server.fakeDNSEngine == nil { // or expose an Engine() accessor
    return errors.New("FakeDNS engine not wired; register dns.FakeDNSEngine first")
}
ips, ttl, err := server.QueryIP(ctx, domain, opt)

Type guard

func hasFakeDNSEngine(s Server) bool {
    f, ok := s.(*FakeDNSServer)
    return ok && f.fakeDNSEngine != nil
}

Prevention

When it happens

Trigger: Calling QueryIP on a *FakeDNSServer whose fakeDNSEngine field is nil — typically when the FakeDNS server is built via NewFakeDNSServerConfig outside a fully-started Xray instance, or when the dns.FakeDNSEngine feature failed to register before the nameserver started.

Common situations: Embedding Xray-core as a library and creating a FakeDNS nameserver without wiring the fake DNS engine feature; startup ordering issues where the DNS server starts before the fake DNS pool is created; config that enables fakeDNS in the DNS section but the cache/fakedns feature is missing.

Related errors


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