{"record":{"id":"1adc079c7a511977","repo":"SubtitleEdit/subtitleedit","slug":"kokoro-tts-server-exited-during-startup-code-nat","errorCode":null,"errorMessage":"kokoro-tts-server exited during startup (code {NativeExitCodeHelper.Describe(process.ExitCode)}). {hint} Output: {tail}","messagePattern":"kokoro-tts-server exited during startup \\(code (.+?)\\)\\. (.+?) Output: (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/ui/Features/Video/TextToSpeech/Engines/KokoroTtsCpp.cs","lineNumber":364,"sourceCode":"            process.BeginOutputReadLine();\n\n            _serverProcess = process;\n            _serverPort = port;\n            HookProcessExitOnce();\n\n            var deadline = DateTime.UtcNow.AddSeconds(60);\n            while (DateTime.UtcNow < deadline)\n            {\n                ct.ThrowIfCancellationRequested();\n                if (process.HasExited)\n                {\n                    var tail = SnapshotStderr(stderrBuffer);\n                    _serverProcess = null;\n                    _serverPort = 0;\n                    // An empty tail plus a 0xC00000xx code means the loader killed it before main -\n                    // NativeExitCodeHelper explains those instead of just printing the raw number.\n                    var hint = NativeExitCodeHelper.GetHint(process.ExitCode, \"Kokoro TTS\", GetSetFolder());\n                    throw new InvalidOperationException(\n                        $\"kokoro-tts-server exited during startup (code {NativeExitCodeHelper.Describe(process.ExitCode)}).\"\n                        + (hint == null ? string.Empty : \" \" + hint)\n                        + $\" Output: {tail}\");\n                }\n                if (await ProbeHealthAsync(port, TimeSpan.FromSeconds(1), ct))\n                {\n                    return;\n                }\n                await Task.Delay(TimeSpan.FromMilliseconds(500), ct);\n            }\n\n            var lastOutput = SnapshotStderr(stderrBuffer);\n            StopServerInternal();\n            throw new TimeoutException(\n                $\"kokoro-tts-server did not report healthy within 60s. Last output: {lastOutput}\");\n        }\n        finally\n        {","sourceCodeStart":346,"sourceCodeEnd":382,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Features/Video/TextToSpeech/Engines/KokoroTtsCpp.cs#L346-L382","documentation":"InvalidOperationException from KokoroTtsCpp.EnsureServerRunningAsync when the kokoro-tts-server process exits before the first successful health probe. Distinctively, this one decodes the native exit code via NativeExitCodeHelper: an empty log + a 0xC00000xx code means the Windows loader killed the process before main (missing DLL, bad arch), and a human hint is appended. The described code and the last stderr tail are included.","triggerScenarios":"Missing the Visual C++ runtime / required DLL (loader kills before main → 0xC0000135); running a 64-bit binary on a 32-bit OS or vice versa; model/voices path arguments invalid so the server exits immediately; the working directory (GetSetFolder) lacks the relative dict/vocab.txt the binary expects.","commonSituations":"Fresh Windows machine missing the VC++ redistributable; copied the binary without its dependency DLLs; wrong-architecture build downloaded; models folder moved so the `-m`/`-V` paths are wrong.","solutions":["Read the hint from NativeExitCodeHelper — a 0xC0000135 means install the VC++ redistributable / required runtime.","Read the `Output:` tail for the server's own startup error (e.g. `cannot find model`, `failed to open vocab`).","Confirm the `-m` modelPath and `-V` voicesPath files exist and match the binary's expected format.","Ensure the working directory (GetSetFolder) contains dict/vocab.txt the binary references.","Install the matching architecture (x64) build of kokoro-tts-server."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-flight: VC++ runtime present + assets in place\nif (!HasVcRedist()) PromptInstallVcRedist();\nif (!File.Exists(modelPath) || !File.Exists(voicesPath)) { PromptDownloadKokoroModels(); return; }","typeGuard":null,"tryCatchPattern":"try { await kokoroEngine.Speak(...); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"exited during startup\"))\n{\n    // NativeExitCodeHelper hint explains loader kills (0xC0000135 etc.)\n    ShowDiagnostics(ex.Message); // includes hint + Output tail\n}","preventionTips":["Install the Visual C++ redistributable on fresh Windows machines.","Download the correct architecture (x64) of kokoro-tts-server.","Keep dict/vocab.txt present in the working directory (GetSetFolder).","Verify model/voices paths match the binary's expectations before startup."],"tags":["kokoro","process-startup","native-exit-code","loader","tts"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}