UBA fails compiling modules with "Exited with error code -1"

Hello,

Many team members are failing to compile the engine from source (unmodified source code from github + Platforms dir from Perforce). This reproduces in both UE v5.6.0 & v5.6.1.

The team does not have a distributed Horde setup so it’s just using UBA local mode (the default). When compiling the engine many modules fail to compile with this generic error:

Compile [x64] Module.Engine.39.cpp: Exited with error code -1 . The build will fail.And the final compile result is:

CompilationResultException: OtherCompilationErrorWorkaround

Disabling UBA fixes the issue and all affected team members can compile the engine successfully. Disabled via BuildConfiguration.xml :

<?xml version="1.0" encoding="utf-8" ?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
 	<BuildConfiguration>
		<bAllowUBAExecutor>false</bAllowUBAExecutor>
	</BuildConfiguration>
</Configuration>

Debugging

I followed the [UBA Practical Debugging [Content removed] page (very useful) to build Debug UBA libs and used the -UbaLog and -UbaDetailedLog flags to generate UBA logs:

D:\P4\unreal5.6_sample\Engine\Binaries\ThirdParty\DotNet\8.0.300\win-x64\dotnet.exe D:\P4\unreal5.6_sample\Engine\Binaries\DotNET\UnrealBuildTool\UnrealBuildTool.dll "-Target=AGSDKSampleEditor Win64 Development -Project=\"D:\P4\unreal5.6_sample\AGSDKSample\AGSDKSample.uproject\"" "-Target=ShaderCompileWorker Win64 Development -Project=\"D:\P4\unreal5.6_sample\AGSDKSample\AGSDKSample.uproject\" -Quiet" -WaitMutex -FromMsBuild -architecture=x64 -UbaLog -UbaDetailedLog -log="D:\UbaDebug\UnrealBuildTool_Log_UbaDetailedLog_Enabled_DEBUG_2025-09-04_1015.log"I’ve attached both the UBA logs (zipped) and UBT log of a failed engine compile.

Analysis

In my attached UBT logs the following modules failed to compile (note: many more fail when donig a full rebuild):

6796	 Compile [x64] Module.Engine.39.cpp: Exited with error code -1 . The build will fail.
6803	 Compile [x64] Module.Engine.50.cpp: Exited with error code -1 . The build will fail.
6809	 Compile [x64] Module.GeometryCollectionNodes.3.cpp: Exited with error code -1 . The build will fail.
6813	 Compile [x64] Module.MovieSceneTracks.2.cpp: Exited with error code -1 . The build will fail.

Unfortunately the UBA logs don’t give a clear smoking gun for the failure (to me at least). The common pattern is the last line in all the UBA logs for the compile failed modules is:

T IsProcessorFeaturePresent 23 -> Success

I hope the attached logs give enough info as to what is going on, but let me know if more information would be helpful. Note that not everyone on the team is experiencing this issue, but many are, so I suspect it might be hardware query related.

Cheers,

Andrej

p.s. In the [UBA Practical Debugging [Content removed] page it mentions several UBA libs to build in Debug, but it doesn’t mention the UbaDetours lib, which I had to also build in order to generate UBA logs.

Steps to Reproduce
Compile the engine source in UBA local mode and many modules fail to compile with a very generic error. Sample failure:

 Compile [x64] Module.Engine.39.cpp: Exited with error code -1 . The build will fail.
 Compile [x64] Module.Engine.39.cpp: WorkingDirectory D:\P4\unreal5.6_sample\Engine\Source
 Compile [x64] Module.Engine.39.cpp: C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\bin\Hostx64\x64\cl.exe @"../Intermediate/Build/Win64/x64/UnrealEditor/Development/Engine/Module.Engine.39.cpp.obj.rsp" 

Hi,

We constantly fix UBA issues, could you take the latest binaries from UE5/Main (//UE5/Main/Engine/Binaries/Win64/UnrealBuildAccelerator/) and replace the one you have for UE-5.6? They should be a drop-in replacement. If that doesn’t fix the issue, we will take a look.

Regards,

Patrick

Thanks for the detailed information. I looked in Module.Engine.39.cpp.obj.log and I can see it is suddenly cut off which indicates a crash. UBA is supposed to log out a callstack on things like access violations but only if the crash is in uba code (inside the UbaDetours.dll).. so the theory is that UBA is returning something bad back to the cl.exe code which explodes.

What I would do myself in this scenario is to enable WER which will write out a crashdump and then you can paste that crashdump in here. Do you mind doing that?

Thanks,

Henrik

Hi Henrik,

Thank you Epic for getting the big guns to look at this (i.e. UBA author) :slight_smile:

I started up the Windows Error Report (WER) service and was able to get some crash dumps out (%LOCALAPPDATA%\CrashDumps for anyone following). The crash is in UbaDetours.dll and appears to be part of some string processing (wcstombs_s). Please see the notes below.

UbaDetours.dll/.pdb Location

When I first loaded the crash dump the Engine\Binaries\Win64\UnrealBuildAccelerator\x64\UbaDetours.pdb was not matched with UbaDetours.dll. Looking in the VS modules view it seems that UBT actually loads the dll from Engine\Binaries\DotNET\UnrealBuildTool\runtimes\win-x64\native

cl.exe.135684__UBA_BINARIES_AT_CL45505155.7z

  • Full crash dump (2.8GB expanded)
  • Using the UBA binaries from Perforce at CL 45505155 (Sep 4)

Comprehensive callstack after loading UbaDetours.pdb:

UbaDetours.dll!_invoke_watson(const wchar_t * expression=0x0000000000000000, const wchar_t * function_name=0x0000000000000000, const wchar_t * file_name=0x0000000000000000, unsigned int line_number=16, unsigned __int64 reserved=0) Line 237
	at minkernel\crts\ucrt\src\appcrt\misc\invalid_parameter.cpp(237)
UbaDetours.dll!_invalid_parameter_internal(const wchar_t * expression=0x0000000000000000, const wchar_t * function_name=0x0000000000000000, const wchar_t * file_name=0x0000000000000000, unsigned int line_number=0, unsigned __int64 reserved=0, __crt_cached_ptd_host & ptd={...}) Line 113
	at minkernel\crts\ucrt\src\appcrt\misc\invalid_parameter.cpp(113)
UbaDetours.dll!_wcstombs_internal(unsigned __int64 * pConvertedChars=0x0000000317dfd5f0, char * dst, unsigned __int64 sizeInBytes=0, const wchar_t * src, unsigned __int64 n=18446744073709551615, __crt_cached_ptd_host & ptd={...}) Line 392
	at minkernel\crts\ucrt\src\appcrt\convert\wcstombs.cpp(392)
UbaDetours.dll!wcstombs_s(unsigned __int64 * pConvertedChars, char * dst, unsigned __int64 sizeInBytes, const wchar_t * src, unsigned __int64 n=18446744073709551615) Line 416
	at minkernel\crts\ucrt\src\appcrt\convert\wcstombs.cpp(416)
[Inline Frame] UbaDetours.dll!uba::StringBufferBase::Parse(char * outCapacity, unsigned __int64) Line 452
	at D:\build\++Fortnite\Sync\Engine\Source\Programs\UnrealBuildAccelerator\Core\Private\UbaStringBuffer.cpp(452)
[Inline Frame] UbaDetours.dll!uba::Shared_GetModuleFileNameA(const wchar_t *) Line 1378
	at D:\build\++Fortnite\Sync\Engine\Source\Programs\UnrealBuildAccelerator\Detours\Private\Windows\UbaDetoursFunctionsKernelBase.inl(1378)
UbaDetours.dll!uba::Detoured_GetModuleFileNameA(HINSTANCE__ * hModule, char * lpFilename=0x0000000317dfdf30, unsigned long nSize) Line 1386
	at D:\build\++Fortnite\Sync\Engine\Source\Programs\UnrealBuildAccelerator\Detours\Private\Windows\UbaDetoursFunctionsKernelBase.inl(1386)
AppProfiler.x64.dll!00000001800154fd()
AppProfiler.x64.dll!0000000180009355()
AppProfiler.x64.dll!000000018000a7d8()
AppProfiler.x64.dll!00000001800097e2()
AppProfiler.x64.dll!0000000180008dd7()
AppProfiler.x64.dll!00000001800019ed()
AppProfiler.x64.dll!000000018000193b()
AppProfiler.x64.dll!00000001800016f7()
AppProfiler.x64.dll!0000000180032e52()
AppProfiler.x64.dll!000000018004f9df()
ntdll.dll!00007ffbfb020cee()
ntdll.dll!00007ffbfaf329fe()
ntdll.dll!00007ffbfaf3196c()
ntdll.dll!00007ffbfaefbc7a()
ntdll.dll!00007ffbfaefae03()
ntdll.dll!00007ffbfaec88d4()
ntdll.dll!00007ffbfaec84e0()
ntdll.dll!00007ffbfaf15d80()
KERNELBASE.dll!LoadLibraryExW()
UbaDetours.dll!uba::Detoured_LoadLibraryExW(const wchar_t * lpLibFileName, void * hFile=0x0000000000000000, unsigned long dwFlags=0) Line 2923
	at D:\build\++Fortnite\Sync\Engine\Source\Programs\UnrealBuildAccelerator\Detours\Private\Windows\UbaDetoursFunctionsKernelBase.inl(2923)

cl.exe.43648__UBA_BINARIES_AT_CL45806006.7z

  • Attached in the next post, because apparently only one attachment per post is allowed :confused:
  • Minidump (132MB uncompressed)
  • Using the UBA binaries from Perforce at CL 45806006 (Sep 12)
  • Not very useful callstack
UbaDetours.dll!_invoke_watson(const wchar_t * expression, const wchar_t * function_name, const wchar_t * file_name, unsigned int line_number, unsigned __int64 reserved) Line 237
	at minkernel\crts\ucrt\src\appcrt\misc\invalid_parameter.cpp(237)

Compile Command Line

D:\P4\unreal5.6_sample\Engine\Binaries\ThirdParty\DotNet\8.0.300\win-x64\dotnet.exe D:\P4\unreal5.6_sample\Engine\Binaries\DotNET\UnrealBuildTool\UnrealBuildTool.dll "-Target=AGSDKSampleEditor Win64 Development -Project=\"D:\P4\unreal5.6_sample\AGSDKSample\AGSDKSample.uproject\"" "-Target=ShaderCompileWorker Win64 Development -Project=\"D:\P4\unreal5.6_sample\AGSDKSample\AGSDKSample.uproject\" -Quiet" -WaitMutex -FromMsBuild -architecture=x64 -UbaLog -UbaDetailedLog -log="D:\AndrejTemp\__Unreal_5.6_Installation__\Unreal Build Accelerator Debugging\Logs\UBA_UE5-Main-Stream_CL45806006_WERS_ENABLED_2025-09-16_1801.log"

Hopefully these nuggets of data will help figure out the issue. Let me know if you need more details.

Cheers,

Andrej

Attaching cl.exe.43648__UBA_BINARIES_AT_CL45806006.7zsince only 1 attachment per post is permitted

ah, great info thanks.

what it looks like is that an extra dll is being injected into the process. I have never seen AppProfiler.x64.dll before

Searching online it says

“Pharos Print Management software, such as Print Scout or Toner Saver, that injects itself into other 64-bit applications to monitor or control their functionality”

I will take a look at the dumps today

Do you think you can send me the uba binaries and pdb too (UbaDetours.dll and UbaDetours.pdb are the important ones)

ok, I did a speculative fix.. tested changing to WideCharToMultiByte instead of wcstombs_s since it seems to fail more gracefully.

Can you locally do these modifications and see if it works.. error handling is so hard to validate in the detouring code :slight_smile:

	u32 StringBufferBase::Parse(char* out, u64 outCapacity) const
	{
		#if PLATFORM_WINDOWS
		return WideCharToMultiByte(CP_ACP, 0, data, count+1, out, outCapacity, nullptr, nullptr);
		//size_t destLen;
		//if (wcstombs_s(&destLen, out, outCapacity, data, outCapacity-1) != 0)
		//	return 0;
		//return (u32)destLen;
		#else
		if (outCapacity == 0)
			return 0;
		u32 toCopy = Min(u32(outCapacity - 1), count);
		memcpy(out, data, toCopy);
		out[toCopy] = 0;
		return toCopy;
		#endif
	}

and

DWORD Shared_GetModuleFileNameA(const tchar* func, HMODULE hModule, LPSTR lpFilename, DWORD nSize)
{
	// Verified called from used applications.. and does not automatically call W version
	StringBuffer<> temp;
	nSize = Min(nSize, (DWORD)temp.capacity);
	DWORD res = Shared_GetModuleFileNameW(func, hModule, temp.data, nSize);
	u32 res2 = temp.Parse(lpFilename, res);
	if (res2 == 0)
		return 0;
	return res2 - 1;
}

If it works I will submit this (and remove the commented out code)

I might also add AppProfiler.x64.dll to the list of dlls that is not allowed to be loaded.. I’ve already done it to a few nvidia dlls that injects themselves in all dlls in the same way (grrrr, who want some random program to be allowed to be injected in every process on your machine)

Hi Henrik,

I’ll give that a shot. That code is in UbaCore, but from what I can tell there is no UbaCore.dll generated, but rather the UbaCore module is just referenced by UbaDetours (and other modules), correct? So I should just be compiling the UbaDetours.dll with those changes.

> I might also add AppProfiler.x64.dll to the list of dlls that is not allowed to be loaded..

> I’ve already done it to a few nvidia dlls that injects themselves in all dlls in the same way

> (grrrr, who want some random program to be allowed to be injected in every process on your machine)

Seriously. Injecting into another process seems like something that should only be done when it is really, really necessary. Not just to get the application name performing the print.

Cheers,

Andrej

Hi Henrik,

I gave it a whirl and it appears to have worked! I was able to compile the engine with your code changes. I had to do one minor downcast on ‘outCapacity’ to compile successfully:

	u32 StringBufferBase::Parse(char* out, u64 outCapacity) const
	{
#if PLATFORM_WINDOWS
		return WideCharToMultiByte(CP_ACP, 0, data, count + 1, out, static_cast<int>(outCapacity), nullptr, nullptr);

In Shared_GetModuleFileNameA(), should there be an error log instead of the removed UBA_ASSERT?

Testing

  1. I first built all the UBA DLLs without your fixes (i.e. all the DLLs found in Engine\Binaries\Win64\UnrealBuildAccelerator\x64)
  2. Cleaned my project & engine
  3. Ran a cmd line build and validated that “error code -1” was reproduced (it did pretty much immediately).
    1. dotnet.exe D:\P4\unreal5.6_sample\Engine\Binaries\DotNET\UnrealBuildTool\UnrealBuildTool.dll “-Target=AGSDKSampleEditor Win64 Development -Project=\“D:\P4\unreal5.6_sample\AGSDKSample\AGSDKSample.uproject\”” …
  4. Added your fixes, cleaned my project & engine and re-ran the same cmd line build.
  5. Verified the full engine compile completed without “error code -1”

Suggestions

I have some suggestions for easing debugging of UBA issues:

  1. If possible, could UBT use UbaDetours.dll and UbaHost.dll from it’s default build location of Engine\Binaries\Win64\UnrealBuildAccelerator\x64 (with the other UBA DLLs) instead of just those 2 DLLs copied and used from Engine\Binaries\DotNET\UnrealBuildTool\runtimes\win-x64\native
    1. At one point I had DLLs from 2 different builds in those locations and kept on getting this error while compiling: “Exited with error code 9666. This action will retry without UBA”
  2. Include the debug libs as part of running gitdependencies so it’s easy to swap out the development binaries and get UBA-specific logs from C:\ProgramData\Epic\UnrealBuildAccelerator\sessions
  3. This might a stretch, but running CrashReporter (optionally) to capture and log stack traces in the event of a UBA crash.

I would appreciate if you could update this thread when the updated DLLs are pushed and available via gitdependencies. I’d rather have the fix come directly from Epic rather than me sharing around custom built DLLs to multiple teams. I’ll get a shady reputation :wink:

Cheers,

Andrej

great. Yep, there has been a few of these issues where unexpected dlls are injected into the compiler/linker processes and do something that is not properly handled. Regarding your suggestions

  1. The reason it is setup this way is because now and then people are running UBT and p4 at the same time for whatever reason (not recommended).. and if UBT loads directly from the submitted folder we get locked files and hung syncs. I agree with you, I also want it to be used directly from that location but this is the reason
  2. I don’t know what gitdependencies is :slight_smile: But if you mean submit debug binaries into p4.. yes we’ve talked about that (our p4 depot is mirrored to github)
  3. We have very few crashes over millions of runs and when it crashes we usually get callstacks in the log. You are one of the first people reporting crashes.. not sure why this was not properly caught by the vectored exception handler. I suspect the code is not checking deep enough to see if uba is in the callstack (it only catches crashes where uba is in the callstack). Usually the issue is weird build errors which is much more nasty to dissect.

I’m running the uba preflights right now.. the scale uba is being used at inside epic is just insane. My support load has gone down to quite low right now but every time I have to change something fundamental I panic a little bit :slight_smile: Supporting things like compiling android target remotely on a Mac… or compiling shaders remotely on linux.. or stage file compression for ps5... lol there are so many things that can break

Hi Henrik,

Yup I totally understand some panic when anything goes awry with the scale and extent of UBA :slight_smile: You don’t want to be that person responsible for time lost of n devs x m hours!

In terms of my suggestion #1, yeah I get you can’t control Perforce. Maybe the alternative would be to have all the DLLs reside under Engine\Binaries\DotNET\UnrealBuildTool\runtimes\win-x64\native

For #2, gitdepedencies is part of the setup script for end users building the engine from source (detailed in the git readme). Essentially it downloads all the binaries (like UBA DLLs) for end users so they don’t have to compile all the programs, etc. (plus some assets). But at Epic you probably never go through that process and sync directly from Perforce + build. So what I originally meant was to have the UBA debug dlls also be downloaded as part of the end user setup script.

Cheers,

Andrej

  1. Putting them in that folder would reintroduce the issue of files being locked by UBT when people sync p4 and p4 hang for a very long time trying to write to a file that is being in use. So UBT must load UbaHost.dll from a different folder than version control is writing to (hence the stupid copy).. I wish windows could work like linux on this one
  2. I agree, we need to get the debug dlls in there.. will bring it up with the build farm people. :slight_smile:

New binaries are in… we hit a snag with ps4 ltcg/thinlto with the original fix so I had to do another fix on top of that.. but should be good now :slight_smile:

Thanks for reporting this

Hi Henrik,

I thought the updated UBA DLLs would be downloaded when running the setup.bat script, but that doesn’t seem to be the case. The output shows it just updated this one file:

D:\P4\unreal5.6_sample>Setup.bat
Checking dependencies...
The following file(s) have been modified:
  Engine/Binaries/Win64/UnrealBuildAccelerator/x64/UbaHost.toml (read only)
Would you like to overwrite your changes (y/n)? y
Updating dependencies: 100% (1/1), 0.1/0.1 MiB | 0.01 MiB/s, done.
Installing prerequisites...
 
D:\P4\unreal5.6_sample>

I then manually synced Perforce CL 46085239 (//UE5/Main/Engine/Binaries/Win64/UnrealBuildAccelerator/x64/) and replaced the DLLs on my local machine in these 2 locations:

D:\P4\unreal5.6_sample\Engine\Binaries\Win64\UnrealBuildAccelerator\x64
D:\P4\unreal5.6_sample\Engine\Binaries\DotNET\UnrealBuildTool\runtimes\win-x64\native

I just want to double-check that the expected update for users is the 2nd option and the DLLs won’t actually be part of the setup.bat download until the next Unreal Engine release?

Thanks,

Andrej

p.s. I’ve also verified that I’ve successfully completed an engine build with the updated UBA Dlls from Perforce.

Hi Andrej,

The Setup.bat in UE 5.6.1 will download the binaries corresponding to the one stored in the 5.6.1 P4 version: //UE5/Release-5.6/Engine/Binaries/Win64/UnrealBuildAccelerator/. Normally, if you get the UE5 main branch from GitHub and run Setup.bat for that branch, it should pick up the corresponding binaries stored iin //UE5/Main/Engine/Binaries/Win64/UnrealBuildAccelerator/x64/. But since you have P4 access, syncing from UE5/Main is just easier and you did the correct thing. The UE 5.7 will have those (or newer) version of the binaries that Henrik submitted to P4.

Regards,

Patrick

Got it. Yeah I can see how it can be problematic to have the 5.6.1 setup.bat pull in newer/patched binaries because then some people on a team may end up with different DLL versions if they setup today vs someone who setup a couple months ago. The good thing is there is this post to follow if more devs run into this issue.

Thanks for you help :slight_smile:

Andrej

Hi Patrick,

Unfortunately the same `error code -1` compile error persists:

[360/4002] Compile [x64] Module.BlueprintGraph.8.cpp
 Compile [x64] Module.MeshDescription.cpp: Exited with error code -1 . The build will fail.
 Compile [x64] Module.MeshDescription.cpp: WorkingDirectory D:\P4\unreal5.6_sample\Engine\Source
 Compile [x64] Module.MeshDescription.cpp: C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\bin\Hostx64\x64\cl.exe @"../Intermediate/Build/Win64/x64/UnrealEditor/Development/MeshDescription/Module.MeshDescription.cpp.obj.rsp" 
[361/4002] Compile [x64] Module.MeshDescription.cpp
[362/4002] Link [x64] UnrealEditor-BlueprintGraph.lib

My Steps:

  1. I used the UBA libs synced from //UE5/Main/Engine/Binaries/Win64/UnrealBuildAccelerator/x64/ and tried both these CLs:
    1. CL 45505155 (submitted Sep4)
    2. CL 45806006 (submitted Sep12)
  2. Replaced this entire dir in my engine: \Engine\Binaries\Win64\UnrealBuildAccelerator\x64
  3. Note: engine built from github tag 5.6.1-release: commit 6978b63c8951e57d97048d8424a0bebd637dde1d
  4. In Visual Studio I ran a “Clean” on my game project.
  5. Built via the command line:
    1. D:\P4\unreal5.6_sample\Engine\Binaries\ThirdParty\DotNet\8.0.300\win-x64\dotnet.exe D:\P4\unreal5.6_sample\Engine\Binaries\DotNET\UnrealBuildTool\UnrealBuildTool.dll “-Target=AGSDKSampleEditor Win64 Development -Project=\“D:\P4\unreal5.6_sample\AGSDKSample\AGSDKSample.uproject\”” “-Target=ShaderCompileWorker Win64 Development -Project=\“D:\P4\unreal5.6_sample\AGSDKSample\AGSDKSample.uproject\” -Quiet” -WaitMutex -FromMsBuild -architecture=x64 -UbaLog -UbaDetailedLog -log=“D:\AndrejTemp\__Unreal_5.6_Installation__\Unreal Build Accelerator Debugging\Logs\UBA_UE5-Main-Stream_CL45505155_2025-09-11_1735.log”

I’m attaching a summary of the build log, which encompasses the start, failures and the end (UBA libs @ CL 45505155).

Since the UBA libs are release versions, no UBA-specific logs were generated in C:\ProgramData\Epic\UnrealBuildAccelerator\sessions

Notes:

One thing I’ve noticed that on successive compiles the amount of `error code -1` seems to decrease. In this round of testing I started with 4, then next compile 2, then 1. But that last one stays after a 3 more compile attempts.

Although I replaced the UBA libs from Perforce, these UBA-related Editor libs are still built as part of the engine:

  • Engine\Plugins\UbaController\Binaries\Win64\UnrealEditor-UbaController.dll
  • D:\P4\unreal5.6_sample\Engine\Binaries\Win64\UnrealEditor-UbaCoordinatorHorde.dll

Let me know if you need more details.

Cheers,

Andrej