stride3d/stride · error · InvalidOperationException

Vulkan call returned

Error message

Vulkan call {call} returned {vkResult}

What it means

GraphicsDevice.CheckResult converts any non-Success VkResult from a Vulkan API call into an InvalidOperationException naming the call and the raw result code (e.g. VK_ERROR_OUT_OF_DEVICE_MEMORY, VK_ERROR_DEVICE_LOST). It is the generic Vulkan error propagation point used by the whole Vulkan backend.

Solutions

  1. Read the VkResult in the message: DEVICE_LOST → handle/reset the device, OUT_OF_*_MEMORY → reduce resource usage
  2. Update GPU drivers to latest vendor release
  3. Validate your scene resource sizes and reduce VRAM pressure (textures, buffers)
  4. Enable Vulkan validation layers during development to catch the underlying API misuse
  5. Handle device-lost in your engine loop by recreating the GraphicsDevice
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    GraphicsDevice.ExecuteCommandLists(count, commandLists);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("returned VkResult"))
{
    if (ex.Message.Contains("ErrorDeviceLost"))
        RecreateGraphicsDevice();
    else
        Logger.Error(ex, "Vulkan call failed.");
}

Prevention

When it happens

Trigger: Any Vulkan call checked via CheckResult returns a failure result — e.g. vkQueueSubmit2 during ExecuteCommandLists failing with OUT_OF_MEMORY or DEVICE_LOST, or device creation calls failing.

Common situations: Device lost after GPU driver reset/TDR; out-of-host/device memory from oversized resources; invalid usage causing VK_ERROR_INVALID_DEVICE_ADDRESS_EXT; driver bugs on certain GPU/driver combinations.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/2ccf07237ba673e5. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs:366

                    for (int i = 0; i < count; i++)
                        DebugAggregateLocalCounters(commandLists[i].Builder.DebugScopeExtractLocalCounters());
                }
            }

            // Collect resources
            for (int i = 0; i < count; i++)
            {
                RecycleCommandListResources(commandLists[i], nextCommandListFenceValue);
            }

            nativeResourceCollector.Release();
            graphicsResourceLinkCollector.Release();
        }

        internal void CheckResult(VkResult vkResult, [CallerArgumentExpression("vkResult")] string call = null)
        {
            if (vkResult != VkResult.Success)
                throw new InvalidOperationException($"Vulkan call {call} returned {vkResult}");
        }

        /// <summary>
        ///   Initializes the platform-specific features of the Graphics Device once it has been fully initialized.
        /// </summary>
        private unsafe partial void InitializePostFeatures()
        {
            if (IsDebugMode)
                DebugMessengerDevice = this;
        }

        // Vulkan messages fire synchronously through the messenger callback, which logs them
        // inline. End-of-frame drain just dumps the scope tree if anything fired.
        partial void DrainDebugMessages()
        {
            if (debugSawDrawIssue)
                DebugDumpTree();
            debugSawDrawIssue = false;

View on GitHub (pinned to 96fad776d2)