If you've packaged an Unreal Engine project, you've probably seen this at the bottom of a log:
AutomationTool exiting with ExitCode=25 (Error_UnknownCookFailure)
Or, in the editor, PackagingResults: Error: Unknown Cook Failure. Search for it and you'll find years of forum threads where someone pastes those last lines, someone else asks for the full log, and the thread dies.
I wanted to know what these logs actually look like when you know the cause. So I built a small test project and broke it on purpose, in a controlled and repeatable way, on Unreal Engine 5.4.4 and 5.8.3.
The setup
- 13 clean baseline runs (command line and editor) that package successfully.
-
24 sabotaged runs across six scenarios, each run twice on both engine versions:
- a project plugin that crashes in
StartupModule()during the cook, - the same plugin copied twice under
Plugins/, - a
.Build.cswhose class name doesn't match the module, - a
.upluginthat declares a module with no rules file, - deleted assets still referenced by a soft or a hard reference.
- a project plugin that crashes in
All logs are scrubbed of user, machine and path information. To be clear about the limits: this is one project on one machine, and every failure is synthetic. It shows how Unreal reports these failures, not how often they happen in the wild.
Finding 1: the exit code is a stage, not a cause
Three codes carry most of the meaning:
-
ExitCode=8: UnrealBuildTool failed. The cook never started. -
ExitCode=25 (Error_UnknownCookFailure): the cook failed. -
ExitCode=3(on theTook ...s to run UnrealEditor-Cmd.exeline): the return code of the cook process itself.
Of my 16 failed runs, 12 ended with ExitCode=8. That ratio comes from the scenarios I chose, but it's a useful reminder: before you dig through cook output, check whether there was a cook at all.
Finding 2: the real crash is above a wall of C# stack trace
Here's the plugin crash, from the Cook-*.txt log (5.4.4, paths anonymized):
LogWindows: Error: begin: stack for UAT
LogWindows: Error: === Critical error: ===
LogWindows: Error:
LogWindows: Error: Fatal error!
LogWindows: Error:
LogWindows: Error: Unhandled Exception: EXCEPTION_ACCESS_VIOLATION writing address 0x0000000000000000
LogWindows: Error:
LogWindows: Error: [Callstack] 0x00007ffa774f1604 UnrealEditor-MyPlugin.dll!FMyPluginModule::StartupModule() [C:\Projects\MyProject\Plugins\MyPlugin\Source\MyPlugin\Private\MyPlugin.cpp:21]
LogWindows: Error: [Callstack] 0x00007ffa04e1e42b UnrealEditor-Core.dll!UnknownFunction []
LogWindows: Error: [Callstack] 0x00007ffa0479a944 UnrealEditor-Projects.dll!UnknownFunction []
Two details matter. First, the first line tagged Error: is begin: stack for UAT, a banner and not a cause, so a naive "find the first error" search stops in the wrong place. Second, the useful line is the first non-engine module in the callstack: UnrealEditor-MyPlugin.dll. That names the plugin to update or disable.
In the main Log.txt, the crash is relayed at line 7057 of 7095. The last ~40 lines are an AutomationTool stack trace, Cook failed., and the ExitCode=25 line. If you only paste the tail, you paste the part with no information.
Finding 3: the line right after the cause looks like a different error
Here's the duplicated plugin (5.8.3, Log.txt):
...\Plugins\Copies\MyPlugin\...\MyPlugin.Build.cs(5,14): error CS0101: The namespace '<global namespace>' already contains a definition for 'MyPlugin'
...\Plugins\Copies\MyPlugin\...\MyPlugin.Build.cs(7,9): error CS0111: Type 'MyPlugin' already defines a member called 'MyPlugin' with the same parameter types
Expecting to find a type to be declared in a target rules named 'MyProjectEditorTarget'.
Result: Failed (RulesError)
There's no "duplicate plugin" message anywhere. UnrealBuildTool compiles every .Build.cs of the project into one C# assembly, so two copies of the same plugin declare the same class twice, and the C# compiler reports CS0101. The next line, Expecting to find a type to be declared in a target rules named..., looks like a classic broken-Target.cs error with its own forum threads, but here it's only a consequence.
The fix is in the first line: its path points to the second copy (Plugins/Copies/...). Every subfolder of Plugins/ is scanned, including the one where you parked a backup.
Finding 4: a successful build can still ship a broken game
8 of the 24 sabotaged runs ended with BUILD SUCCESSFUL and ExitCode=0. All of them were assets deleted while still referenced:
- 5.4.4, soft reference: no trace in any log.
- 5.4.4, hard reference: a
Warning: Failed to load '/Game/...': Can't find file. - 5.8.3, both: the same Display-level line,
Package ... has a dependency on package ... which does not exist. You can't tell soft from hard in the log.
If a mesh or sound is missing in your packaged build, search the log for those strings even when packaging "worked".
Finding 5: my own expectation was wrong once
One scenario was designed to trigger Expecting to find a type to be declared in a module rules named '...'. On both versions it produced Could not find definition for module '...' instead: a different error, with a different fix (the module has no .Build.cs at all). That's now its own rule. Error messages are specific, so match the exact text.
And one from the real world
A few days ago someone on Reddit shared a packaging log that started like this (anonymized):
LogTurnkeySupport: Warning: Turnkey failed to run properly, full Turnkey output:
Running AutomationTool...
...
Building 1 projects...
...\Build\Scripts\obj\...\MyProject.Automation.AssemblyInfo.cs(13,12): error CS0579: Duplicate 'System.Reflection.AssemblyCompanyAttribute' attribute
Everything about the first line says "your platform SDK is broken". It isn't. Before Turnkey can check any SDK, AutomationTool compiles the project's own automation scripts (Build/Scripts/*.Automation.csproj), and that compile failed: the assembly attributes were generated twice. The usual suspects are leftover obj/bin folders or a project copy that's off in some other way. In this case, deleting obj didn't help, but re-downloading the project did. So if cleaning the build folders doesn't work, get a fresh copy of the project before touching your SDK.
Same lesson as Finding 3: the scary line at the top is the messenger, the error CS line underneath is the message.
A checklist that works without any tool
- Check the exit code: 8 means build stage, 25 means cook stage.
- Search from the top for
Error:,error CS,error C,Assertion failed,Unhandled Exception. - Skip banners and summaries:
begin: stack for UAT,Fatal error!,PackagingResults,Cook failed,ExitCode=. - If
Log.txtsaysUnrealBuildTool failed. See log for more details, open theUBA-*.txtit names. - If Turnkey complains but
error CSlines follow, fix the C# error first: it's a script build problem, not an SDK one. - Even on success, search for
which does not existandCan't find file.
Disclosure
I turned these rules into a free, in-browser decoder: cookfail.dev. It documents 26 error patterns and detects 23 of them automatically. 6 were reproduced in the lab described here, one comes from that real user's log, and the rest come from forum threads and haven't been reproduced yet.
Your log never leaves your browser. If the decoder gets it wrong, the feedback button lets you tell me the actual cause, and real-world logs are exactly what this test set needs most.
Top comments (0)