{"record":{"id":"42322230bf7d1fff","repo":"XTLS/Xray-core","slug":"unable-to-locate-a-fake-dns-engine","errorCode":null,"errorMessage":"Unable to locate a fake DNS Engine","messagePattern":"Unable to locate a fake DNS Engine","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/dns/nameserver_fakedns.go","lineNumber":30,"sourceCode":"\tfakeDNSEngine dns.FakeDNSEngine\n}\n\nfunc NewFakeDNSServer(fd dns.FakeDNSEngine) *FakeDNSServer {\n\treturn &FakeDNSServer{fakeDNSEngine: fd}\n}\n\nfunc (FakeDNSServer) Name() string {\n\treturn \"FakeDNS\"\n}\n\n// IsDisableCache implements Server.\nfunc (s *FakeDNSServer) IsDisableCache() bool {\n\treturn true\n}\n\nfunc (f *FakeDNSServer) QueryIP(ctx context.Context, domain string, opt dns.IPOption) ([]net.IP, uint32, error) {\n\tif f.fakeDNSEngine == nil {\n\t\treturn nil, 0, errors.New(\"Unable to locate a fake DNS Engine\").AtError()\n\t}\n\n\tvar ips []net.Address\n\tif fkr0, ok := f.fakeDNSEngine.(dns.FakeDNSEngineRev0); ok {\n\t\tips = fkr0.GetFakeIPForDomain3(domain, opt.IPv4Enable, opt.IPv6Enable)\n\t} else {\n\t\tips = f.fakeDNSEngine.GetFakeIPForDomain(domain)\n\t}\n\n\tnetIP, err := toNetIP(ips)\n\tif err != nil {\n\t\treturn nil, 0, errors.New(\"Unable to convert IP to net ip\").Base(err).AtError()\n\t}\n\n\terrors.LogInfo(ctx, f.Name(), \" got answer: \", domain, \" -> \", ips)\n\n\tif len(netIP) > 0 {\n\t\treturn netIP, 1, nil // fakeIP ttl is 1","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/app/dns/nameserver_fakedns.go#L12-L48","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the dns.FakeDNSEngine feature is registered and started on the core.Instance before the FakeDNS nameserver is used","If constructing servers manually, inject the engine via the constructor path that sets fakeDNSEngine instead of using the bare server struct","Check startup logs for 'failed to register fake DNS engine' style messages and fix the underlying registration error first"],"exampleFix":"// before\nserver := &dns.FakeDNSServer{} // no engine attached\nips, ttl, err := server.QueryIP(ctx, \"example.com\", opt) // error\n\n// after\n// register the fake DNS feature on the instance so the nameserver\n// is created with its engine (see app/dns/fakedns.go):\ncore.Must(core.RegisterConfig((*fakedns.Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {\n    return fakedns.New(ctx, cfg.(*fakedns.Config))\n}))\n// then create the FakeDNS nameserver through the instance, not standalone","handlingStrategy":"validation","validationCode":"// Before using a FakeDNS nameserver, confirm the engine feature is present:\nif server.fakeDNSEngine == nil { // or expose an Engine() accessor\n    return errors.New(\"FakeDNS engine not wired; register dns.FakeDNSEngine first\")\n}\nips, ttl, err := server.QueryIP(ctx, domain, opt)","typeGuard":"func hasFakeDNSEngine(s Server) bool {\n    f, ok := s.(*FakeDNSServer)\n    return ok && f.fakeDNSEngine != nil\n}","tryCatchPattern":null,"preventionTips":["Create the FakeDNS nameserver through a started core.Instance, never as a bare struct","Register the fakedns config type before instance start so the engine feature resolves","In tests, inject a stub dns.FakeDNSEngine into the server before calling QueryIP"],"tags":["dns","fake-dns","feature-registration","config"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}