bevyengine/bevy · error · GltfError

invalid buffer uri: {0}. asset path error={1}

Error message

invalid buffer uri: {0}. asset path error={1}

What it means

Raised at loader/mod.rs:1944-1947 when a buffer's uri is not a data URI and LoadContext::resolve_embed_str(uri) fails, yielding InvalidBufferUri(uri, ParseAssetPathError). Bevy resolves buffer URIs relative to the glTF asset's own path so the .bin counts as an embedded/child asset; URIs that are absolute (http://, /abs, C:\) or otherwise cannot live under the parent asset path fail resolution.

Source

Thrown at crates/bevy_gltf/src/loader/mod.rs:105

    #[error("unsupported primitive mode")]
    UnsupportedPrimitive {
        /// The primitive mode.
        mode: Mode,
    },
    /// Invalid glTF file.
    #[error("invalid glTF file: {0}")]
    Gltf(#[from] gltf::Error),
    /// Binary blob is missing.
    #[error("binary blob is missing")]
    MissingBlob,
    /// Decoding the base64 mesh data failed.
    #[error("failed to decode base64 mesh data")]
    Base64Decode(#[from] base64::DecodeError),
    /// Unsupported buffer format.
    #[error("unsupported buffer format")]
    BufferFormatUnsupported,
    /// The buffer URI was unable to be resolved with respect to the asset path.
    #[error("invalid buffer uri: {0}. asset path error={1}")]
    InvalidBufferUri(String, ParseAssetPathError),
    /// Invalid image mime type.
    #[error("invalid image mime type: {0}")]
    #[from(ignore)]
    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.

View on GitHub (pinned to 396ca72708)

Solutions

  1. Download the .bin and rewrite the uri to a relative path next to the .gltf ("scene.bin").
  2. Keep the exporter's output folder intact: .gltf, .bin and textures must stay siblings.
  3. Use forward slashes; Bevy's asset paths are '/'-separated.
  4. Single-file GLB avoids external references entirely.

Example fix

// (before)
"buffers": [{ "uri": "http://cdn.example.com/scene.bin" }]
// (after) file shipped next to the model
"buffers": [{ "uri": "scene.bin" }]
Defensive patterns

Strategy: validation

Validate before calling

fn buffer_uris_resolve(model: &std::path::Path, json: &serde_json::Value) -> Vec<String> {
    json["buffers"].as_array().unwrap_or(&vec![]).iter()
        .filter_map(|b| b["uri"].as_str())
        .filter(|u| !u.starts_with("data:"))
        .filter(|u| u.contains("://") || u.starts_with('/') || std::path::Path::new(u).is_absolute())
        .map(String::from)
        .collect() // non-empty => loading will fail with InvalidBufferUri
}

Try / catch

match err {
    GltfError::InvalidBufferUri(uri, e) => {
        error!("buffer uri {uri} cannot resolve under the asset path ({e}); localize the file and use a relative uri");
    }
    other => return Err(other.into()),
}

Prevention

When it happens

Trigger: "uri": "http://cdn.example.com/scene.bin"; "uri": "/shared/scene.bin"; a uri that escapes the asset root; Windows-style backslash separators in the uri.

Common situations: Models downloaded with remote references left in; asset folders moved after export so relative structure broke; CI copying only some files.

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/d2df59440e564e2a. Report an issue: GitHub.