bevyengine/bevy · error · GltfError
failed to generate tangents: {0}
Error message
failed to generate tangents: {0} What it means
GltfError::GenerateTangentsError (#[from] bevy_mesh::GenerateTangentsError) wraps the failure of mesh.generate_tangents() at loader/mod.rs:862. The loader computes tangents for triangle-list meshes that lack a TANGENT attribute but need them (normal-mapped materials); generation requires positions, normals, UVs and a triangle index list, and fails on missing attributes, degenerate/zero-area triangles, or too few vertices.
Source
Thrown at crates/bevy_gltf/src/loader/mod.rs:128
InvalidImageMimeType(String),
/// Error when loading a texture. Might be due to a disabled image file format feature.
#[error("You may need to add the feature for the file format: {0}")]
ImageError(#[from] TextureError),
/// The image URI was unable to be resolved with respect to the asset path.
#[error("invalid image uri: {0}. asset path error={1}")]
InvalidImageUri(String, ParseAssetPathError),
/// Failed to read bytes from an asset path.
#[error("failed to read bytes from an asset path: {0}")]
ReadAssetBytesError(#[from] ReadAssetBytesError),
/// Failed to load asset from an asset path.
#[error("failed to load asset from an asset path: {0}")]
AssetLoadError(#[from] AssetLoadError),
/// Missing sampler for an animation.
#[error("Missing sampler for animation {0}")]
#[from(ignore)]
MissingAnimationSampler(usize),
/// Failed to generate tangents.
#[error("failed to generate tangents: {0}")]
GenerateTangentsError(#[from] bevy_mesh::GenerateTangentsError),
/// Failed to generate morph targets.
#[error("failed to generate morph targets: {0}")]
MorphTarget(#[from] bevy_mesh::morph::MorphBuildError),
/// Circular children in Nodes
#[error("GLTF model must be a tree, found cycle instead at node indices: {0:?}")]
#[from(ignore)]
CircularChildren(String),
/// Failed to load a file.
#[error("failed to load file: {0}")]
Io(#[from] Error),
}
/// Loads glTF files with all of their data as their corresponding bevy representations.
#[derive(TypePath)]
pub struct GltfLoader {
/// List of compressed image formats handled by the loader.
pub supported_compressed_formats: CompressedImageFormats,View on GitHub (pinned to 396ca72708)
Solutions
- Re-export with UVs, normals and tangents (Blender: enable 'Export Tangents').
- Or ensure the mesh has POSITION + NORMAL + TEXCOORD_0 and valid triangle indices so generation succeeds.
- Remove the normal map from the material if tangents are unavailable.
- Clean degenerate triangles in a DCC (merge by distance / custom normals tools).
Example fix
// Blender glTF export options (before) // [ ] Export Tangents, UVs off // (after) // [x] Export Tangents and UV Coordinates, geometry = triangles
Defensive patterns
Strategy: validation
Validate before calling
fn tangent_generation_safe(doc: &gltf::Document) -> bool {
doc.meshes().flat_map(|m| m.primitives()).all(|p| {
let sems: Vec<_> = p.attributes().iter().map(|(s, _)| s).collect();
let needs_tangents = p.material().normal_texture().is_some();
!needs_tangents
|| sems.contains(&gltf::Semantic::Tangents)
|| (sems.contains(&gltf::Semantic::Positions)
&& sems.contains(&gltf::Semantic::Normals)
&& sems.contains(&gltf::Semantic::TexCoords(0))
&& p.indices().is_some())
})
} Try / catch
match err {
GltfError::GenerateTangentsError(e) => {
warn!("tangent generation failed ({e:?}); re-export with UVs+normals or without normal map");
}
other => return Err(other.into()),
} Prevention
- Always export UVs and normals for normal-mapped meshes.
- Prefer exporting tangents directly (Blender 'Export Tangents').
- Remove normal maps from meshes lacking UV data.
When it happens
Trigger: A primitive with a normal-map texture but no TANGENT accessor, where the mesh also lacks UV or NORMAL attributes (or indices); meshes containing degenerate triangles that break mikktspace-style winding tests.
Common situations: Exporters with 'export UVs/normals' disabled; decimated or LOD meshes; CAD tessellations with slivers; flat-colored models given a normal-mapped material after the fact.
Related errors
- unsupported primitive mode
- failed to generate morph targets: {0}
- cannot generate tangents for {0:?}
- missing indices
- missing vertex attributes '{0}'
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/44b7b2b78567fb2f.
Report an issue: GitHub.