{"record":{"id":"97a3b99c83978fd2","repo":"netchx/netch","slug":"aiodns-start-failed","errorCode":null,"errorMessage":"AioDNS start failed.","messagePattern":"AioDNS start failed\\.","errorType":"exception","errorClass":"MessageException","httpStatus":null,"severity":"error","filePath":"Netch/Controllers/DNSController.cs","lineNumber":23,"sourceCode":"namespace Netch.Controllers;\n\npublic class DNSController : IController\n{\n    public string Name => \"DNS Service\";\n\n    public async Task StartAsync()\n    {\n        var aioDnsConfig = Global.Settings.AioDNS;\n\n        Dial(NameList.TYPE_REST, \"\");\n        Dial(NameList.TYPE_LIST, Path.GetFullPath(Constants.AioDnsRuleFile));\n        // TODO remove ListenPort setting\n        Dial(NameList.TYPE_LISN, $\"127.0.0.1:{aioDnsConfig.ListenPort}\");\n        Dial(NameList.TYPE_CDNS, $\"{aioDnsConfig.ChinaDNS}\");\n        Dial(NameList.TYPE_ODNS, $\"{aioDnsConfig.OtherDNS}\");\n\n        if (!await InitAsync())\n            throw new MessageException(\"AioDNS start failed.\");\n    }\n\n    public Task StopAsync()\n    {\n        return FreeAsync();\n    }\n}","sourceCodeStart":5,"sourceCodeEnd":30,"githubUrl":"https://github.com/netchx/netch/blob/9d99eb1c5a2acbf2a34f2600f94242601019a300/Netch/Controllers/DNSController.cs#L5-L30","documentation":"Thrown by DNSController.StartAsync after the native AioDNS engine's InitAsync() (P/Invoke aiodns_init in aiodns.bin) returned false. The controller first Dials listen address, China DNS, Other DNS, and the rule file path into the engine, then asks it to initialize; a false return means the engine rejected the configuration or could not bind. The message itself gives no detail, so the real cause is only visible in the Verbose Dial logs or the engine's own output.","triggerScenarios":"AioDNS ListenPort (Global.Settings.AioDNS.ListenPort) is already bound by another process; the rule file bin\\aiodns.conf (Constants.AioDnsRuleFile) is missing so TYPE_LIST Dial points at a non-existent path; ChinaDNS/OtherDNS values are malformed; aiodns.bin native binary is missing/corrupt/wrong architecture so aiodns_init throws or returns false.","commonSituations":"Two Netch instances configured to the same AioDNS listen port; user edited settings to a port in the Windows excluded range; fresh install where bin\\aiodns.conf was not shipped; antivirus quarantined aiodns.bin; 32-bit bin on 64-bit OS.","solutions":["Check logging\\AioDNS or the Verbose logs for the exact Dial value that broke init, and the aiodns_init return path.","Change Global.Settings.AioDNS.ListenPort to a free port (avoid the Windows reserved range from `netsh int ipv4 show excludedportrange tcp`).","Verify bin\\aiodns.conf exists under NetchDir; restore it from a clean release if missing.","Confirm ChinaDNS and OtherDNS are valid DNS URIs/hosts; defaults live in Constants.DefaultPrimaryDNS.","Reinstall Netch to restore aiodns.bin if it was removed by antivirus."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before calling _aioDnsController.StartAsync(), verify the inputs InitAsync needs.\nvar cfg = Global.Settings.AioDNS;\nif (cfg.ListenPort == 0)\n    throw new InvalidOperationException(\"AioDNS ListenPort is not set\");\nMainController.PortCheck(cfg.ListenPort, \"AioDNS\", PortType.UDP);\nif (!File.Exists(Path.GetFullPath(Constants.AioDnsRuleFile)))\n    throw new InvalidOperationException($\"{Constants.AioDnsRuleFile} missing\");\nif (File.Exists(Path.Combine(Global.NetchDir, \"bin\", \"aiodns.bin\")) == false)\n    throw new InvalidOperationException(\"aiodns.bin missing from bin\\\\\");","typeGuard":null,"tryCatchPattern":"try { await _aioDnsController.StartAsync(); }\ncatch (MessageException ex) when (ex.Message == \"AioDNS start failed.\")\n{\n    Log.Error(ex, \"AioDNS init returned false; see Dial logs for the bad value\");\n    throw;\n}","preventionTips":["Validate AioDNS ListenPort is free (use MainController.PortCheck) before Start.","Ship and verify bin\\aiodns.conf at startup.","Enable Verbose logging during development to see every Dial value passed to the engine.","Never run two Netch instances with the same AioDNS listen port."],"tags":["dns","native-interop","config","startup"],"backgroundTag":null,"analyzedSha":"9d99eb1c5a2acbf2a34f2600f94242601019a300","analyzedAt":"2026-08-13T14:12:19.105Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}