Zurück zum Blog

Behebung des Unreal Engine UBA Executor UBT-Errors in UE 5.8 Source Builds

Veröffentlicht am 27. Juni 2026
Behebung des Unreal Engine UBA Executor UBT-Errors in UE 5.8 Source Builds

Kurz und knapp

Dieser Guide beschreibt die Ursache und Behebung des UBA Executor UBT-Errors, der beim Kompilieren von Unreal Engine 5.8.0 aus den Sources auftritt. Der Fehler resultiert daraus, dass die Executor-Factory fälschlicherweise versucht, den UBA Executor für rekursive UBT-Aufrufe wie den Build des UnrealHeaderTools zu verwenden. Entwickler können das Problem entweder global über die Konfigurationsdatei BuildConfiguration.xml umgehen oder den C#-Sourcecode von UBT patchen, um die Build-Beschleunigung für den Haupt-Build beizubehalten.

Wenige Dinge bremsen die Dynamik eines Studios so sehr aus wie ein fehlerhafter Engine-Build – besonders wenn man Unreal Engine 5.8.0 aus dem Source Code kompiliert und Visual Studio mit einer kryptischen Exception abbricht. Der Build schlägt mit einer Unhandled Exception fehl, die direkt auf UBAExecutor.cs verweist. Dieser spezifische Blocker, bekannt als der unreal engine uba executor ubt error, stoppt die Compilation vollständig. Er verhindert, dass der Build-Graph die Generierung kritischer Hilfsprogramme wie das UnrealHeaderTool abschließt. In diesem Guide analysieren wir, warum der Unreal Build Accelerator (UBA) Probleme mit verschachtelten Aufrufen (nested calls) hat, wie die Standardkonfiguration fehlschlägt und wie Sie Ihren Engine-Sourcecode patchen, um eine funktionierende Build-Pipeline wiederherzustellen.

Die Architektur des Build-Systems verstehen

Um zu verstehen, warum dieser Fehler auftritt, müssen wir untersuchen, wie das Unreal Build Tool (UBT) die Compilation orchestriert. Unreal Engine-Codebases sind gigantisch und enthalten oft zehntausende Source-Dateien. Um diese effizient zu kompilieren, fungiert UBT als Meta-Build-System, das Dependency-Graphen generiert und Compile-Actions verteilt.

Was ist der Unreal Build Accelerator?

Epic Games hat den Unreal Build Accelerator (UBA) als Standard-Compilation-Executor eingeführt, um ältere Distributionssysteme abzulösen. UBA soll die Compilation beschleunigen, indem es ein leichtgewichtiges virtualisiertes Dateisystem (VFS) nutzt, um Datei-I/O-Operationen abzufangen. Es leitet Compiler-Tasks über mehrere lokale Kerne um oder verteilt sie über Horde-Build-Nodes.

Auf einer standardmäßigen 64-Core-Build-Maschine kann UBA die Zeiten für einen Clean-Engine-Build von etwa 90 Minuten auf unter 25 Minuten reduzieren. Da UBA jedoch auf einen zentralen lokalen Agenten angewiesen ist, um den I/O abzufangen, erfordert es eine strikte Kontrolle darüber, wie Compiler-Prozesse gestartet (spawned) werden.

Der Mechanismus rekursiver UBT-Aufrufe

Während eines Compilation-Runs stößt UBT häufig auf Targets, die gebaut werden müssen, bevor die Haupt-Engine-Binaries kompiliert werden können. Beispielsweise muss UBT vor dem Kompilieren des UnrealEditor-Executables erst das UnrealHeaderTool (UHT) kompilieren, um Header-Dateien zu parsen und Reflection-Metadaten zu generieren.

Um dies zu erreichen, startet der primäre UBT-Prozess einen verschachtelten, sekundären UBT-Prozess, um das erforderliche Target zu bauen. Dieser verschachtelte Aufruf wird als rekursiver UBT-Aufruf (recursive UBT call) bezeichnet. Wenn ein rekursiver UBT-Aufruf aktiv ist, setzt UBT ein internes Flag (UnrealBuildTool.IsRecursive = true) und gibt Umgebungsvariablen (environment variables) weiter, um den Prozess als verschachtelt zu markieren.

Warum der UBA Executor bei rekursiven Aufrufen abstürzt

Der Crash tritt auf, weil der UBA Executor nicht dafür ausgelegt (architected) ist, verschachtelte Compilation-Schleifen zu unterstützen. Werfen wir einen Blick auf den typischen Call Stack, der von UBT ausgegeben wird, wenn dieser Fehler in Visual Studio auftritt:

Unhandled exception: Exception: UBA executor is not expected to be invoked from a recursive UBT call.
   at UnrealBuildTool.UBAExecutor.Init(IEnumerable`1 targetDescriptors, ILogger logger) in UnrealEngine\Engine\Source\Programs\UnrealBuildTool\Executors\UnrealBuildAccelerator\UBAExecutor.cs:line 315
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at UnrealBuildTool.UBAExecutor.ExecuteActionsAsync(IEnumerable`1 inputActions, ILogger logger) in UnrealEngine\Engine\Source\Programs\UnrealBuildTool\Executors\UnrealBuildAccelerator\UBAExecutor.cs:line 617
   at UnrealBuildTool.ActionGraph.InternalExecuteActions(ActionExecutor Executor, List`1 ActionsToExecute, ILogger Logger) in UnrealEngine\Engine\Source\Programs\UnrealBuildTool\Actions\ActionGraph.cs:line 435

Der Safety Check in UBAExecutor.cs

In der UBAExecutor.Init-Methode (etwa auf Zeile 315 der UBAExecutor.cs) erzwingt die Engine explizit einen Recursion Safety Check:

// Engine/Source/Programs/UnrealBuildTool/Executors/UnrealBuildAccelerator/UBAExecutor.cs
public void Init(IEnumerable<TargetDescriptor> TargetDescriptors, ILogger Logger)
{
    if (UnrealBuildTool.IsRecursive)
    {
        throw new Exception("UBA executor is not expected to be invoked from a recursive UBT call.");
    }
    
    // Virtualized file system and network initialization follow...
}

Dieser Safety Check hat einen wichtigen Grund. Der lokale UBA-Agent bindet sich an bestimmte TCP-Ports, um mit den virtualisierten Compiler-Hilfsprozessen zu kommunizieren.

Wenn ein rekursiver UBT-Aufruf versuchen würde, eine zweite Instanz des UBA-Executors zu initialisieren, würden beide Instanzen versuchen, sich an dieselben Network Sockets zu binden, und es käme zu Konflikten bei den Hooks des virtualisierten Dateisystems. Dies würde zu Socket-Zuweisungsfehlern (socket allocation errors), Filesystem-Corruption oder unendlichen Build-Deadlocks führen. Die Exception dient hier als Schutzbarriere.

Die eigentliche Ursache: Fehler bei der Executor-Auswahl

Der tatsächliche Bug in den Source Builds der Unreal Engine 5.8.0 ist nicht dieser Safety Check. Vielmehr liegt es daran, dass die Executor-Factory-Logik rekursive Aufrufe nicht korrekt verarbeitet.

Wenn UBT bestimmt, welcher Executor verwendet werden soll, fragt es die Klasse ExecutorFactory.cs ab. Die Factory prüft, ob UBA auf der Host-Maschine aktiviert und verfügbar ist.

Sie prüft jedoch nicht, ob der aktuelle UBT-Prozess eine rekursive Ausführung ist. Infolgedessen versucht die Factory beim Start des sekundären UBT-Prozesses zum Kompilieren des UnrealHeaderTool, dem verschachtelten Build den UBAExecutor zuzuweisen, was den Crash in der Init-Methode auslöst.

Die XML-Konfigurations-Falle

Viele Entwickler versuchen, dieses Problem durch Modifizieren der globalen Datei BuildConfiguration.xml zu umgehen. Der Standardrat in älteren Forenbeiträgen lautet, UBA durch Deaktivieren des folgenden Tags auszuschalten:

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

Warum bAllowUBA in UE 5.8 ignoriert wird

Wenn Sie die obige XML-Konfiguration auf einen Unreal Engine 5.8.0 Source Build anwenden, versucht der Compiler trotzdem, UBA zu starten, und wirft die Exception. Das liegt daran, dass das Build-Konfigurationssystem der Engine refactored wurde.

Das alte Flag bAllowUBA ist deprecated und nicht mehr mit der Logik zur Executor-Auswahl verknüpft. Stattdessen wird das Verhalten von UBA über zwei separate Properties gesteuert: bAllowUBAExecutor und bAllowUBALocalExecutor.

Da UBT bAllowUBAExecutor in Ihrer XML-Datei nicht findet, fällt es auf den Standardwert true zurück. Dadurch wird Ihr Versuch, UBA zu deaktivieren, stillschweigend überschrieben.

Korrekte XML-Struktur für die UBA-Konfiguration

Um UBA über Konfigurationsdateien erfolgreich zu deaktivieren, müssen Sie die aktualisierten XML-Property-Namen verwenden. Nachfolgend finden Sie die korrekte Struktur, um UBT zur Nutzung der standardmäßigen lokalen Executors zu zwingen:

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

Diese Konfiguration umgeht UBA erfolgreich. Allerdings bedeutet das vollständige Deaktivieren von UBA auch, dass Sie die erheblichen Geschwindigkeitsvorteile bei der Compilation für Ihre primären Build-Actions verlieren.

Schritt-für-Schritt-Anleitung zur Behebung des Fehlers

Je nach Ihrem Workflow können Sie dieses Problem entweder global durch Modifizieren Ihrer XML-Konfiguration lösen oder den UBT-Sourcecode direkt patchen, um die Build-Beschleunigung für nicht-rekursive Compilations beizubehalten.

Methode 1: Der BuildConfiguration.xml Override

Wenn Sie den Engine-Sourcecode nicht modifizieren möchten, können Sie UBA global deaktivieren. Dies ist der schnellste Weg, Ihr Projekt zum Kompilieren zu bringen, erhöht jedoch die Compile-Zeiten für Clean Builds je nach Hardware um ca. 40 % bis 60 %.

  1. Suchen oder erstellen Sie Ihre globale BuildConfiguration.xml-Datei. Unter Windows befindet sich diese normalerweise unter %AppData%\Roaming\Unreal Engine\UnrealBuildTool\BuildConfiguration.xml. Unter Linux finden Sie sie unter ~/.config/Unreal Engine/UnrealBuildTool/BuildConfiguration.xml.
  2. Öffnen Sie die XML-Datei in einem Texteditor.
  3. Ersetzen Sie den Inhalt durch das unten gezeigte, aktualisierte XML-Schema.
  4. Speichern Sie die Datei und starten Sie Ihren Visual Studio-Build neu.
<?xml version="1.0" encoding="utf-8" ?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
    <BuildConfiguration>
        <bAllowUBAExecutor>false</bAllowUBAExecutor>
        <bAllowUBALocalExecutor>false</bAllowUBALocalExecutor>
    </BuildConfiguration>
</Configuration>

Methode 2: UBT-Sourcecode patchen (Empfohlen)

Da Sie Unreal Engine 5.8 aus den Sources kompilieren, ist das Patchen des UBT-C#-Sourcecodes die empfohlene Lösung. Dadurch kann UBA für Ihr primäres Compilation-Target ausgeführt werden, während für rekursive Aufrufe ein Fallback auf den standardmäßigen ParallelExecutor erzwungen wird.

  1. Navigieren Sie zum UBT-Source-Verzeichnis: Engine/Source/Programs/UnrealBuildTool/Executors/.
  2. Öffnen Sie die Datei ExecutorFactory.cs in Visual Studio oder einem Texteditor.
  3. Suchen Sie die Create-Methode. Diese Methode wertet Ihre Konfiguration aus und gibt den entsprechenden ActionExecutor zurück.
  4. Modifizieren Sie das Conditional Statement der UBA-Auswahl, um eine Prüfung auf rekursive UBT-Runs hinzuzufügen.
// Engine/Source/Programs/UnrealBuildTool/Executors/ExecutorFactory.cs

public static ActionExecutor Create(BuildConfiguration BuildConfiguration, List<TargetDescriptor> TargetDescriptors, ILogger Logger)
{
    // Check if UBA is allowed, available, and NOT running recursively
-   if (BuildConfiguration.bAllowUBAExecutor && UBAExecutor.IsAvailable())
+   if (BuildConfiguration.bAllowUBAExecutor && UBAExecutor.IsAvailable() && !UnrealBuildTool.IsRecursive)
    {
        return new UBAExecutor(BuildConfiguration, Logger);
    }

    // Fall back to IncrediBuild if configured
    if (BuildConfiguration.bAllowXGE)
    {
        return new XGEExecutor(BuildConfiguration, Logger);
    }

    // Fall back to standard ParallelExecutor
    return new ParallelExecutor(BuildConfiguration, Logger);
}

Dieser Patch verhindert, dass die verschachtelte UBT-Instanz den UBA Executor auswählt. Stattdessen läuft der rekursive Build (wie das Bauen von UnrealHeaderTool) sicher über den lokalen ParallelExecutor, während Ihre primäre Engine-Compilation weiterhin die volle Leistung von UBA nutzt.

Methode 3: Command-Line-Flags

Wenn Sie Ihren Build-Prozess über benutzerdefinierte Command-Line-Scripts oder CI/CD-Pipelines ausführen, können Sie UBA pro Aufruf deaktivieren. Dies ist besonders nützlich, wenn Sie UBA für lokale Entwickler aktiviert lassen, es aber auf Remote-Build-Servern deaktivieren möchten.

Fügen Sie dazu das Flag -NoUBA an Ihren UBT-Build-Befehl an:

# Example command to build the editor without UBA
Engine\Build\BatchFiles\Build.bat UnrealEditor Win64 Development -NoUBA

Alternativ können Sie UBT zwingen, den standardmäßigen Parallel-Executor zu verwenden, indem Sie diesen explizit mit dem -Executor-Flag angeben:

Engine\Build\BatchFiles\Build.bat UnrealEditor Win64 Development -Executor=Parallel

Bereinigen und Neugenerieren der Build-Umgebung

Nach dem Anwenden einer der oben genannten Lösungen kann das Kompilieren von UBT aufgrund von gecachten Assembly-Dateien oder veralteten Intermediate-Metadaten fehlschlagen. Um sicherzustellen, dass der Fix sauber greift, müssen Sie die generierten Build-Tool-Binaries löschen und die Projektdateien neu generieren.

Für Windows-Umgebungen

Führen Sie die folgenden Befehle in einer Eingabeaufforderung (Command Prompt) oder PowerShell-Instanz aus, die auf Ihr Unreal Engine-Source-Verzeichnis verweist:

:: Delete the cached UBT assembly and build binaries
rd /s /q Engine\Intermediate\Build\UnrealBuildTool
rd /s /q Engine\Binaries\DotNET\UnrealBuildTool

:: Regenerate the project files
GenerateProjectFiles.bat

Für Linux- und macOS-Umgebungen

Führen Sie diese Befehle in Ihrem Terminal aus:

# Remove cached build tool data
rm -rf Engine/Intermediate/Build/UnrealBuildTool
rm -rf Engine/Binaries/DotNET/UnrealBuildTool

# Regenerate project files
./GenerateProjectFiles.sh

Sobald die Umgebung bereinigt ist, öffnen Sie Ihre generierte Solution-Datei (UE5.sln) in Visual Studio und führen Sie einen Rebuild des Targets durch. Der Build sollte nun die Phase der rekursiven Compilation durchlaufen, ohne die Executor-Exception auszulösen.

Best Practices für Unreal Engine Source Builds

Das Bauen eines benutzerdefinierten Engine-Forks aus den Sources bringt verschiedene Herausforderungen bei Compilation, Optimierung und Packaging mit sich. Die Anwendung der folgenden Best Practices hilft Ihnen dabei, eine stabile und hochgradig optimierte Development-Pipeline aufrechtzuerhalten.

1. Concurrency optimieren, um Memory Starvation zu verhindern

Moderne C++-Compiler benötigen erheblichen RAM pro Compilation-Thread. Beim Bauen großer Engine-Module kann UBT mehr parallele Tasks starten, als Ihr System-RAM unterstützen kann, was zu Page-File-Thrashing oder Compiler-Crashes führt.

Sie können die maximale Prozessoranzahl begrenzen, indem Sie die ParallelExecutor-Einstellungen in Ihrer BuildConfiguration.xml-Datei konfigurieren:

<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
    <ParallelExecutor>
        <MaxProcessorCount>16</MaxProcessorCount>
        <ProcessorCountMultiplier>1.0</ProcessorCountMultiplier>
    </ParallelExecutor>
</Configuration>

Begrenzen Sie die Anzahl auf ca. 2 GB RAM pro Thread. Beispielsweise sollte eine Maschine mit 32 GB RAM den MaxProcessorCount auf 16 limitieren.

2. Asset Stripping für Dedicated Server meistern

Wenn Sie Ihr Spiel in der Cloud deployen, sollten Sie es vermeiden, unnötige Client-Assets (wie UI-Texturen, Audio und Meshes) in Ihre Dedicated Server-Binary zu kompilieren. Dies reduziert die Startzeiten und den Memory-Footprint des Servers, was für eine effiziente Skalierung von Server-Fleets entscheidend ist.

Um zu erfahren, wie Sie Ihre Build-Scripts konfigurieren, um diese Assets auszuschließen, folgen Sie unserem ausführlichen Guide zum Thema Unreal Engine Dedicated Server Asset Stripping.

3. Blueprint- und Package-Integrität frühzeitig überprüfen

Ein erfolgreicher Engine-Build garantiert nicht, dass Ihr Projekt fehlerfrei verpackt (packaged) werden kann. Veraltete Blueprints oder Serialisierungsfehler verursachen häufig Crashes in der finalen Packaging-Phase.

Um zu verhindern, dass diese Probleme Ihre Release-Pipeline blockieren, lesen Sie unseren Guide zum Resolving the Unreal Package HasValidBlueprint Ensure Crash, um automatisierte Validierungsprüfungen einzurichten.

4. UBA VFS Caching korrekt konfigurieren

Wenn Sie sich dafür entscheiden, UBA mithilfe des C#-Patches aktiviert zu lassen, konfigurieren Sie den Cache des virtuellen Dateisystems so, dass kompilierte Object-Dateien lokal gespeichert werden. So vermeiden Sie das erneute Kompilieren unveränderter Source-Dateien beim Wechseln von Branches.

Fügen den UnrealBuildAccelerator-Konfigurationsblock zu Ihrer XML-Datei hinzu, um Caching zu aktivieren:

<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
    <UnrealBuildAccelerator>
        <WriteCache>true</WriteCache>
        <Cache>127.0.0.1</Cache>
    </UnrealBuildAccelerator>
</Configuration>

Stellen Sie sicher, dass Ihre Firewall nicht die lokalen Netzwerk-Kommunikationsports von UBA blockiert, die zur Verwaltung des Cache-Synchronisations-Loops verwendet werden.

Optimierung Ihrer Backend-Architektur

Die Behebung von Build-Problemen wie dem unreal engine uba executor ubt error ist entscheidend für einen reibungslosen Development-Workflow. Die Einrichtung einer lokalen Compile-Umgebung ist jedoch nur der erste Schritt bei der Entwicklung eines modernen Multiplayer-Spiels.

Sobald Ihre Custom Engine kompiliert ist und Ihre Dedicated Server bereitstehen, müssen Sie sich den komplexen Herausforderungen der Backend-Infrastruktur stellen. Das Schreiben einer eigenen Server-Orchestrierung, von Matchmaking-Algorithmen und Persistenz-Datenbanken von Grund auf erfordert Wochen an Entwicklungszeit.

Die Einrichtung von Load Balancern, Database Sharding und SSL-Zertifikatsverwaltung kann problemlos 4 bis 6 Wochen dedizierter Arbeit in Anspruch nehmen. Mit horizOn sind diese Backend-Services bereits vorkonfiguriert und bereit für die Skalierung.

Anstatt Infrastruktur-Code zu schreiben, können Sie Spielerdaten, Echtzeit-Lobbys und Server-Skalierung mit wenigen einfachen API-Aufrufen integrieren. Dies ermöglicht es Ihnen, Dedicated Server-Builds zu deployen und den Spieler-State ohne jeglichen Wartungsaufwand zu verwalten. Ihr Team kann sich voll und ganz auf Gameplay-Mechaniken und Engine-Features konzentrieren, während horizOn die Cloud-Infrastruktur übernimmt.

Nächste Schritte

Um diesen Build-Error zu beheben, wählen Sie entweder den schnellen XML-Override oder wenden Sie den C#-Source-Patch in ExecutorFactory.cs an. Sobald Ihre Build-Pipeline reibungslos läuft, sollten Sie nach Wegen suchen, Ihren Deployment-Workflow zu optimieren. Wenn Sie Ihr Multiplayer-Spiel ohne den Overhead des Hostings eigener Server skalieren möchten, testen Sie horizOn kostenlos oder werfen Sie einen Blick in unsere API-Dokumentation, um mehr zu erfahren.


Quelle: Unhandled exception: Exception: UBA executor is not expected to be invoked from a recursive UBT call.