{"record":{"id":"2e5415f348179d2a","repo":"emilk/egui","slug":"failed-to-create-staging-buffer-for-index-data-in","errorCode":null,"errorMessage":"Failed to create staging buffer for index data. Index count: {index_count}. Required index buffer size: {required_index_buffer_size}. Actual size {} and capacity: {} (bytes)","messagePattern":"Failed to create staging buffer for index data\\. Index count: (.+?)\\. Required index buffer size: (.+?)\\. Actual size (.+?) and capacity: (.+?) \\(bytes\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/egui-wgpu/src/renderer.rs","lineNumber":1033,"sourceCode":"            self.index_buffer.slices.clear();\n\n            let required_index_buffer_size = (core::mem::size_of::<u32>() * index_count) as u64;\n            if self.index_buffer.capacity < required_index_buffer_size {\n                // Resize index buffer if needed.\n                self.index_buffer.capacity =\n                    (self.index_buffer.capacity * 2).at_least(required_index_buffer_size);\n                self.index_buffer.buffer = create_index_buffer(device, self.index_buffer.capacity);\n            }\n\n            let index_buffer_staging = queue.write_buffer_with(\n                &self.index_buffer.buffer,\n                0,\n                #[expect(clippy::unwrap_used)] // Checked above\n                NonZeroU64::new(required_index_buffer_size).unwrap(),\n            );\n\n            let Some(mut index_buffer_staging) = index_buffer_staging else {\n                panic!(\n                    \"Failed to create staging buffer for index data. Index count: {index_count}. Required index buffer size: {required_index_buffer_size}. Actual size {} and capacity: {} (bytes)\",\n                    self.index_buffer.buffer.size(),\n                    self.index_buffer.capacity\n                );\n            };\n\n            let mut index_offset = 0;\n            for epaint::ClippedPrimitive { primitive, .. } in paint_jobs {\n                match primitive {\n                    Primitive::Mesh(mesh) => {\n                        let size = mesh.indices.len() * core::mem::size_of::<u32>();\n                        let slice = index_offset..(size + index_offset);\n                        index_buffer_staging\n                            .slice(slice.clone())\n                            .copy_from_slice(bytemuck::cast_slice(&mesh.indices));\n                        self.index_buffer.slices.push(slice);\n                        index_offset += size;\n                    }","sourceCodeStart":1015,"sourceCodeEnd":1051,"githubUrl":"https://github.com/emilk/egui/blob/441971a776322a482e371775219380eca812cfa9/crates/egui-wgpu/src/renderer.rs#L1015-L1051","documentation":"The egui-wgpu renderer uploads egui's tessellated index data into a wgpu staging buffer each frame. When `device.create_buffer` fails to produce the staging buffer (typically because the required size exceeds device limits or memory is exhausted), the renderer panics with the index count, required size, and the actual buffer size/capacity for diagnosis.","triggerScenarios":"A frame whose egui paint job has `index_count` large enough that `required_index_buffer_size` exceeds the wgpu device's buffer-creation capability (e.g. `max_buffer_size` limits or out-of-memory), so `index_buffer_staging` is `None`.","commonSituations":"Rendering extremely large UIs (huge lists / many painted primitives) on GPUs with small buffer limits; misconfigured `DeviceDescriptor` limits lowered below what egui needs; running on emulated/software adapters with constrained memory.","solutions":["Increase wgpu `Limits` on the device (e.g. use `Limits::default()` or downlevel defaults raised, ensure `max_buffer_size` is sufficient).","Reduce UI complexity so per-frame tessellation produces fewer indices (virtualize long lists, cull off-screen content).","Check adapter capabilities: the selected GPU/backend may have small limits; prefer a backend/adapter with larger limits.","Inspect the panic's required vs actual sizes; if required size exceeds max_buffer_size, cap egui painting or split into multiple passes."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let limits = adapter.limits();\nlet required = (index_count as u64) * std::mem::size_of::<u32>() as u64;\nassert!(required <= limits.max_buffer_size, \"egui index buffer {required} exceeds max_buffer_size {}\", limits.max_buffer_size);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Create the wgpu device with adequate Limits (default, not heavily reduced downlevel limits).","Virtualize long lists and cull off-screen widgets to bound per-frame tessellation size.","Log buffer sizes in development to spot growth trends before hitting GPU limits.","Test on the lowest-capability target adapter you plan to support."],"tags":["wgpu","gpu","buffer-allocation","panic"],"backgroundTag":"resource-not-found","analyzedSha":"441971a776322a482e371775219380eca812cfa9","analyzedAt":"2026-09-12T04:29:21.500Z","contentChangedAt":"2026-09-12T04:29:21.500Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}