Several days ago I updated my local full source repo to 5.7.3 and then did some collaborative diagnostics with Claude Code in that repo. I combined observations from this thread (by @mirthost) with my own test results and Claude’s ability to rapidly cross-reference different parts of the code base. After all that, I believe we have a workaround.
Quick Workaround
Edit your project’s Config/DefaultEngine.ini to add or change the following:
[/Script/Engine.RendererSettings]
; r.Vulkan.WaitForIdleOnSubmit=1
r.Vulkan.EnablePipelineLRUCache=1
Having one line commented out is not a typo. For most people, enabling the LRU (least recently used) pipeline cache is sufficient to prevent the error with minimal performance impact. If that doesn’t work for you, also enable r.Vulkan.WaitForIdleOnSubmit to fully serialize CPU/GPU communication and eliminate the race condition — but that option imposes a much larger performance penalty and should only be used if necessary.
I had a project reproducing the error within about two minutes of starting the editor at idle, and crashing immediately if I tried to debug a PCG graph. With both INI flags enabled, the crashes stopped. I then commented out WaitForIdleOnSubmit and restarted — it remains stable. So the lighter-weight setting alone is sufficient for my case.
Technical Analysis
Credit for the root cause analysis goes to @mirthost (who ran Vulkan validation layers and identified the exact violation) and Claude Code (Anthropic’s AI coding assistant, which traced the bug to specific lines in the engine source). I contributed the observation that the crash correlated with editor cleanup/GC activity and the idea of looking for CVARs as a workaround to avoid rebuilding the engine from source.
Running with VK_LAYER_KHRONOS_validation catches the specific violation:
VUID-vkQueueSubmit-pSubmits[19].pCommandBuffers[0] — bound VkPipeline
0x83904300002a854b was destroyed.
This is a use-after-free of VkPipeline handles. The CPU destroys a pipeline object while the GPU still has in-flight command buffers referencing it. This triggers NVRM: Xid 69 (invalid pipeline handle) → VK_ERROR_DEVICE_LOST → render fence never signals → CPU deadlock → SIGABRT.
The bug is in Engine/Source/Runtime/VulkanRHI/Private/VulkanPipeline.cpp, in the function NotifyDeletedGraphicsPSO(). On PC/Linux, the LRU pipeline cache is disabled by default. When a PSO’s (pipeline state object’s) reference count hits zero — triggered by material recompilation, level unloading, garbage collection, editor window close, PCG shader invalidation, or similar events — this function calls:
(*Contained)->DeleteVkPipeline(true); // line ~2502: immediate vkDestroyPipeline
VkPSO->DeleteVkPipeline(true); // line ~2515: immediate vkDestroyPipeline
The true argument bypasses the engine’s deferred deletion queue and calls vkDestroyPipeline() immediately, regardless of whether the GPU is still executing commands that use that pipeline.
When the LRU cache is enabled (via the INI setting above), PSO deletion instead goes through LRURemove(), which checks whether the pipeline was used within the last 3 rendered frames. If it was recently used, it calls DeleteVkPipeline(false) — enqueuing the handle in FDeferredDeletionQueue2 for destruction only after the GPU has finished with it. That safety mechanism already exists in the codebase; the default non-LRU path simply doesn’t use it.
For developers who build from source, the proper two-line fix in VulkanPipeline.cpp is to change true to false at both call sites above, so all PSO destruction routes through the deferred deletion
queue. The CPU-side handle is still cleared immediately; only the actual vkDestroyPipeline call is deferred until the GPU is done.
Forum Notes
For this forum post, I wrote the workaround procedure and test results, Claude Code wrote the technical analysis, and I final-edited the merged post.
I have examined the code change proposed by Claude Code and consider it sensible, but I have not personally tested it because the INI file changes are sufficient for me. Use at your own risk.