{"record":{"id":"44b1119478b6721f","repo":"tailscale/tailscale","slug":"split-dns-unsupported-on-this-windows-version","errorCode":null,"errorMessage":"Split DNS unsupported on this Windows version","messagePattern":"Split DNS unsupported on this Windows version","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"net/dns/manager_windows.go","lineNumber":174,"sourceCode":"func delValue(key registry.Key, name string) error {\n\tif err := key.DeleteValue(name); err != nil && err != registry.ErrNotExist {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// setSplitDNS configures one or more NRPT (Name Resolution Policy Table) rules\n// to resolve queries for domains using resolvers, rather than the\n// system's \"primary\" resolver.\n//\n// If no resolvers are provided, the Tailscale NRPT rules are deleted.\nfunc (m *windowsManager) setSplitDNS(resolvers []netip.Addr, domains []dnsname.FQDN) error {\n\tif m.nrptDB == nil {\n\t\tif resolvers == nil {\n\t\t\t// Just a no-op in this case.\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"Split DNS unsupported on this Windows version\")\n\t}\n\n\tdefer m.nrptDB.NotifyPolicyChanged()\n\tif len(resolvers) == 0 {\n\t\treturn m.nrptDB.DelAllRuleKeys()\n\t}\n\n\tservers := make([]string, 0, len(resolvers))\n\tfor _, resolver := range resolvers {\n\t\tservers = append(servers, resolver.String())\n\t}\n\n\treturn m.nrptDB.WriteSplitDNSConfig(servers, domains)\n}\n\nfunc setTailscaleHosts(logf logger.Logf, prevHostsFile []byte, hosts []*HostEntry) ([]byte, error) {\n\tsc := bufio.NewScanner(bytes.NewReader(prevHostsFile))\n\tconst (","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/tailscale/tailscale/blob/6e0912f97994f927632b34ae9e63b53d6516a6ac/net/dns/manager_windows.go#L156-L192","documentation":"windowsManager.setSplitDNS installs NRPT (Name Resolution Policy Table) rules for split DNS, but the NRPT database is only created when isWindows10OrBetter() is true. If m.nrptDB is nil and resolvers are requested, the manager throws this error: the OS cannot express per-domain resolvers, so SetDNS fails rather than silently routing all queries through Tailscale. If resolvers is nil it is a no-op instead.","triggerScenarios":"SetDNS is called with an OSConfig that includes split-DNS resolvers (config.Routes) on a Windows version older than Windows 10, where NewOSConfigurator left nrptDB nil.","commonSituations":"Running tailscaled on Windows Server 2012/2012 R2 or Windows 8.x; a MagicDNS/exit-node configuration that pushes per-domain resolvers to an old OS; policy or MDM configs assuming NRPT support on machines that predate it.","solutions":["Check SupportsSplitDNS() on the manager before requesting split DNS, and fall back to full-tunnel DNS (set Nameservers only, leave Routes empty).","Upgrade the machine to Windows 10+ so the NRPT path is available.","On the client, disable accepting split DNS (e.g. accept-dns=false) and use a plain resolver config for the old OS."],"exampleFix":"// before — unconditional split DNS request\ncfg := dns.OSConfig{\n    Routes:    routes, // per-domain resolvers -> needs NRPT\n    Addresses: addrs,\n}\nerr := mgr.SetDNS(cfg)\n// after — degrade gracefully on pre-Win10 hosts\nif mgr.SupportsSplitDNS() {\n    cfg.Routes = routes\n}\nerr := mgr.SetDNS(cfg)","handlingStrategy":"validation","validationCode":"// Ask the manager before requesting split DNS\nif len(cfg.Routes) > 0 && !mgr.SupportsSplitDNS() {\n    cfg.Routes = nil // degrade to full-tunnel DNS instead of failing SetDNS\n}\nerr := mgr.SetDNS(cfg)","typeGuard":null,"tryCatchPattern":"On 'Split DNS unsupported on this Windows version', retry SetDNS with config.Routes cleared and only global nameservers set — the NRPT-free path succeeds on the same OS.","preventionTips":["Gate split-DNS configuration on SupportsSplitDNS().","Know your fleet's minimum Windows version before shipping NRPT-dependent policy.","Prefer global-resolver fallbacks on legacy hosts."],"tags":["windows","split-dns","nrpt","windows-version"],"backgroundTag":"split-dns-unsupported","analyzedSha":"6e0912f97994f927632b34ae9e63b53d6516a6ac","analyzedAt":"2026-08-18T08:17:25.280Z","contentChangedAt":"2026-08-18T08:17:25.280Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}