{"record":{"id":"b47fa9c610093ed4","repo":"AvaloniaUI/Avalonia","slug":"surface-handle-can-t-be-0x0","errorCode":null,"errorMessage":"Surface handle can't be 0x0","messagePattern":"Surface handle can't be 0x0","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"critical","filePath":"src/Android/Avalonia.Android/Platform/Vulkan/VulkanSupport.cs","lineNumber":58,"sourceCode":"            {\n                _handle = handle;\n            }\n\n            public double Scaling => _handle.Scaling;\n            public PixelSize Size => _handle.Size;\n            public ulong CreateSurface(IVulkanPlatformGraphicsContext context) =>\n                CreateAndroidSurface(_handle.Handle, context.Instance);\n\n            public void Dispose()\n            {\n                // No-op\n            }\n        }\n\n        private static ulong CreateAndroidSurface(nint handle, IVulkanInstance instance)\n        {\n            if(handle == IntPtr.Zero)\n                throw new ArgumentException(\"Surface handle can't be 0x0\", nameof(handle));\n            var vulkanAndroid = new AndroidVulkanInterface(instance);\n            var createInfo = new VkAndroidSurfaceCreateInfoKHR()\n            {\n\n                sType = VkAndroidSurfaceCreateInfoKHR.VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,\n                window = handle\n            };\n            VulkanException.ThrowOnError(\"vkCreateAndroidSurfaceKHR\",\n                vulkanAndroid.vkCreateAndroidSurfaceKHR(instance.Handle, ref createInfo, IntPtr.Zero, out var surface));\n            return surface;\n        }\n    }\n}\n","sourceCodeStart":40,"sourceCodeEnd":72,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Android/Avalonia.Android/Platform/Vulkan/VulkanSupport.cs#L40-L72","documentation":"Thrown by VulkanSupport.CreateAndroidSurface when the native surface handle passed in is IntPtr.Zero. VkCreateAndroidSurfaceKHR requires a valid ANativeWindow pointer; a zero handle means the window/surface was never created or was destroyed before the Vulkan surface could be built.","triggerScenarios":"Calling CreateSurface(IVulkanPlatformGraphicsContext) when the context's surface handle (typically the InvalidationAwareSurfaceView's native window handle) is zero. Same root cause as the ANativeWindow framebuffer error: surface not yet created, already destroyed, or view detached.","commonSituations":"Selecting the Vulkan render backend while the surface is not ready; lifecycle race during pause/resume; embedding AvaloniaView detached from the window; using Vulkan on a device/config where the surface creation timing differs; combining Vulkan with a custom surface view that yields a zero handle.","solutions":["Ensure the surface is created (SurfaceWindowCreated fired with a valid handle) before the Vulkan graphics context is initialized.","Defer Vulkan surface creation until InvalidationAwareSurfaceView exposes a non-zero native window handle.","On surface destroy, tear down the Vulkan swapchain/surface before the handle goes to zero.","If Vulkan reliability is a concern, fall back to the Skia/Framebuffer backend via .With(new SkiaOptions())."],"exampleFix":"// before\n// vulkan context created eagerly in constructor, surface may be 0x0\n graphicsContext = vulkanPlatform.CreateContext();\n\n// after — wait for a valid surface handle\n_surfaceView.SurfaceWindowCreated += (s, e) =>\n{\n    if (((IPlatformHandle)_surfaceView).Handle != IntPtr.Zero)\n        graphicsContext = vulkanPlatform.CreateContext();\n};","handlingStrategy":"validation","validationCode":"// confirm the surface handle is valid before creating the Vulkan surface\nif (((IPlatformHandle)surfaceView).Handle == IntPtr.Zero)\n    return; // surface not ready\nvar surface = vulkanPlatform.CreateSurface(context);","typeGuard":"static bool HasValidSurfaceHandle(InvalidationAwareSurfaceView? v) => v is IPlatformHandle h && h.Handle != IntPtr.Zero;","tryCatchPattern":null,"preventionTips":["Initialize the Vulkan context only after SurfaceWindowCreated yields a non-zero handle.","Tear down Vulkan surfaces on SurfaceWindowDestroyed before the handle clears.","Gate surface creation on a validated handle in custom embeds.","Fall back to Skia/Framebuffer backend if Vulkan timing proves unreliable on target devices."],"tags":["android","vulkan","surface","rendering","lifecycle"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}