bevyengine/bevy · error · AccessFailed
Malformed vertex attribute data
Error message
Malformed vertex attribute data
What it means
AccessFailed::MalformedData is produced in BufferAccessor::iter (crates/bevy_gltf/src/vertex_attributes.rs:51-56) when gltf::accessor::Iter::new returns None: the accessor cannot be decoded against the loaded buffers. Per the doc comment this covers stride mismatches and buffer-view slicing failures — e.g. accessor byteOffset/byteLength exceeding its bufferView, a view out of bounds of its buffer, or a stride invalid for the data type. It surfaces to callers as ConvertAttributeError::AccessFailed(MalformedData, accessor_index) ('Malformed vertex attribute data in accessor N').
Source
Thrown at crates/bevy_gltf/src/vertex_attributes.rs:35
self,
value: T,
normalized_ctor: impl Fn(T) -> U,
unnormalized_ctor: impl Fn(T) -> U,
) -> U {
if self.0 {
normalized_ctor(value)
} else {
unnormalized_ctor(value)
}
}
}
/// An error that occurs when accessing buffer data
#[derive(Error, Debug)]
pub enum AccessFailed {
/// Accessing the data failed because of an issue like a mismatch in stride,
/// or a buffer view slice failing.
#[error("Malformed vertex attribute data")]
MalformedData,
/// The format supplied is unsupported for this operation.
#[error("Unsupported vertex attribute format")]
UnsupportedFormat,
}
/// Helper for reading buffer data
struct BufferAccessor<'a> {
accessor: gltf::Accessor<'a>,
buffer_data: &'a Vec<Vec<u8>>,
normalization: Normalization,
}
impl<'a> BufferAccessor<'a> {
/// Creates an iterator over the elements in this accessor
fn iter<T: gltf::accessor::Item>(self) -> Result<gltf::accessor::Iter<'a, T>, AccessFailed> {
gltf::accessor::Iter::new(self.accessor, |buffer: gltf::Buffer| {
self.buffer_data.get(buffer.index()).map(Vec::as_slice)View on GitHub (pinned to 396ca72708)
Solutions
- Run gltf-validator — it reports out-of-bounds accessors/bufferViews precisely.
- Re-export the model from the source DCC.
- If you generate glTF yourself, recompute byteOffset/byteLength/stride so every accessor fits inside its bufferView and every view inside its buffer.
Defensive patterns
Strategy: validation
Validate before calling
fn accessors_fit(doc: &gltf::Document, buffers: &[Vec<u8>]) -> bool {
doc.accessors().all(|a| {
a.view().map(|v| {
let buf = buffers.get(v.buffer().index()).map(|b| b.len()).unwrap_or(0);
let end = v.offset() + v.length();
let acc_end = a.offset().unwrap_or(0) + a.size();
end <= buf && acc_end <= v.length()
}).unwrap_or(false)
})
} Try / catch
match err {
ConvertAttributeError::AccessFailed(AccessFailed::MalformedData, idx) => {
error!("accessor {idx} does not decode (offset/length/stride vs buffer); re-export or validate the file");
}
other => return Err(other.into()),
} Prevention
- Make gltf-validator part of the asset import pipeline.
- Never hand-edit accessor byteOffset/byteLength without recomputing bounds.
- Detect truncated downloads by comparing file size with source manifest.
When it happens
Trigger: Any mesh attribute accessor whose declared offsets/lengths/strides disagree with the actual buffer bytes — e.g. after manual JSON edits, corrupt downloads, or exporters writing byteLength wrong; sparse/odd strides not representable by the gltf iterator.
Common situations: Hand-tuned buffer optimizations, files truncated then 'repaired', quantization pipelines writing invalid accessor metadata.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unsupported vertex attribute format
- Vertex attribute {0} has format {1:?} but expected {3:?} for
- cannot convert VertexAttributeValues::{variant} to {into}
- Mesh vertex attributes must be {required:?}, but got {provid
- unsupported primitive mode
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/d24cde8946a8a747.
Report an issue: GitHub.