emilk/egui · critical
Failed to create staging buffer for index data. Index count:
Error message
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) What it means
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.
Source
Thrown at crates/egui-wgpu/src/renderer.rs:1033
self.index_buffer.slices.clear();
let required_index_buffer_size = (core::mem::size_of::<u32>() * index_count) as u64;
if self.index_buffer.capacity < required_index_buffer_size {
// Resize index buffer if needed.
self.index_buffer.capacity =
(self.index_buffer.capacity * 2).at_least(required_index_buffer_size);
self.index_buffer.buffer = create_index_buffer(device, self.index_buffer.capacity);
}
let index_buffer_staging = queue.write_buffer_with(
&self.index_buffer.buffer,
0,
#[expect(clippy::unwrap_used)] // Checked above
NonZeroU64::new(required_index_buffer_size).unwrap(),
);
let Some(mut index_buffer_staging) = index_buffer_staging else {
panic!(
"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)",
self.index_buffer.buffer.size(),
self.index_buffer.capacity
);
};
let mut index_offset = 0;
for epaint::ClippedPrimitive { primitive, .. } in paint_jobs {
match primitive {
Primitive::Mesh(mesh) => {
let size = mesh.indices.len() * core::mem::size_of::<u32>();
let slice = index_offset..(size + index_offset);
index_buffer_staging
.slice(slice.clone())
.copy_from_slice(bytemuck::cast_slice(&mesh.indices));
self.index_buffer.slices.push(slice);
index_offset += size;
}View on GitHub (pinned to 441971a776)
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.
Defensive patterns
Strategy: validation
Validate before calling
let limits = adapter.limits();
let required = (index_count as u64) * std::mem::size_of::<u32>() as u64;
assert!(required <= limits.max_buffer_size, "egui index buffer {required} exceeds max_buffer_size {}", limits.max_buffer_size); Prevention
- 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.
When it happens
Trigger: 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`.
Common situations: 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.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Failed to create staging buffer for vertex data. Vertex coun
- Failed to create image
- Failed to create render state
- You must call .update_buffers() before .render()
- Tried to update a texture that has not been allocated yet.
AI-assisted analysis of emilk/egui@441971a776 (2026-09-12).
Data as JSON: /api/errors/2e5415f348179d2a.
Report an issue: GitHub.