bevyengine/bevy · error · AccessFailed
Unsupported vertex attribute format
Error message
Unsupported vertex attribute format
What it means
AccessFailed::UnsupportedFormat fires from two sites in vertex_attributes.rs: the catch-all of VertexAttributeIter::from_accessor (line 135) when the accessor's (DataType, Dimensions) pair is not in the supported table — FLOAT16 data, matrix types, or exotic combos like I8 Vec3 — and BufferAccessor::with_no_norm (line 64) when a float/uint accessor is marked "normalized": true, which only makes sense for signed/unsigned ints and is rejected. It reaches callers as ConvertAttributeError::AccessFailed(UnsupportedFormat, accessor_index).
Source
Thrown at crates/bevy_gltf/src/vertex_attributes.rs:38
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)
})
.ok_or(AccessFailed::MalformedData)
}View on GitHub (pinned to 396ca72708)
Solutions
- Re-export with float32 for standard attributes, or use one of the supported integer combos (U8/I8/U16/I16 in Vec2/Vec3/Vec4, U32/F32 in all dimensions).
- Remove 'normalized' flags from float accessors.
- If you need half-float or exotic layouts, convert to a supported layout in an offline step before loading.
Example fix
// accessor (before)
{ "componentType": 5123, "type": "VEC3", "normalized": true } // U16 Vec3 unsupported combo
// (after)
{ "componentType": 5126, "type": "VEC3" } // FLOAT Vec3, always supported Defensive patterns
Strategy: validation
Validate before calling
fn accessor_format_supported(a: &gltf::Accessor) -> bool {
use gltf::accessor::{DataType as D, Dimensions as V};
let float_like = matches!(a.data_type(), D::F32 | D::U32);
if a.normalized() && float_like { return false; } // with_no_norm rejects this
matches!((a.data_type(), a.dimensions()),
(D::F32, _) | (D::U32, _)
| (D::I16, V::Vec2) | (D::U16, V::Vec2) | (D::I16, V::Vec4) | (D::U16, V::Vec4)
| (D::I8, V::Vec2) | (D::U8, V::Vec2) | (D::I8, V::Vec4) | (D::U8, V::Vec4)
| (D::U16, V::Vec3) | (D::U8, V::Vec3))
} Type guard
fn is_supported_vertex_format(dt: gltf::accessor::DataType, dims: gltf::accessor::Dimensions) -> bool {
use gltf::accessor::{DataType as D, Dimensions as V};
matches!((dt, dims), (D::F32, _) | (D::U32, _) | (D::I16, V::Vec2) | (D::U16, V::Vec2)
| (D::I16, V::Vec4) | (D::U16, V::Vec4) | (D::I8, V::Vec2) | (D::U8, V::Vec2)
| (D::I8, V::Vec4) | (D::U8, V::Vec4) | (D::U16, V::Vec3) | (D::U8, V::Vec3))
} Try / catch
match err {
ConvertAttributeError::AccessFailed(AccessFailed::UnsupportedFormat, idx) => {
error!("accessor {idx} uses an unsupported componentType/type (or normalized floats); re-export with supported formats");
}
other => return Err(other.into()),
} Prevention
- Disable 'half float' precision in exporters for glTF output.
- Quantize only to U8/U16/I8/I16 Vec2/Vec3/Vec4 combos the loader supports.
- Never set normalized on float accessors.
When it happens
Trigger: POSITION/TEXCOORD stored as VEC3/VEC2 of FLOAT16 (exporter 'half float' option); "normalized": true on a F32 accessor; MAT2/MAT3 attributes; I16 Vec3 colors.
Common situations: DCC precision settings ('Half Float'), KHR_mesh_quantization-style assets using unsupported component types/dimensions, custom attribute pipelines copying whatever the source mesh had.
Related errors
- Malformed vertex attribute data
- 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/1b6f22899b9c6b8a.
Report an issue: GitHub.