bevyengine/bevy · error · TextureError

invalid image mime type: {0}

Error message

invalid image mime type: {0}

What it means

TextureError::InvalidImageMimeType is returned by ImageType::to_image_format (crates/bevy_image/src/image.rs:2333-2334) when ImageFormat::from_mime_type cannot map the string to a known format. from_mime_type (image.rs:451) only recognizes a fixed list (image/png, image/jpeg, image/vnd-ms.dds, image/ktx2, image/x-exr, ...) and each entry is feature-gated via the feature_gate! macro, so the mime may be unknown or its format's cargo feature may be disabled. Bevy throws it because it cannot pick a decoder for the bytes.

Source

Thrown at crates/bevy_image/src/image.rs:2290

    /// Image MIME type is invalid.
    #[error("invalid image mime type: {0}")]
    InvalidImageMimeType(String),
    /// Image extension is invalid.
    #[error("invalid image extension: {0}")]
    InvalidImageExtension(String),
    /// Failed to load an image.
    #[error("failed to load an image: {0}")]
    ImageError(#[from] image::ImageError),
    /// Texture format isn't supported.
    #[error("unsupported texture format: {0}")]
    UnsupportedTextureFormat(String),
    /// Supercompression isn't supported.
    #[error("supercompression not supported: {0}")]
    SuperCompressionNotSupported(String),
    /// Failed to decompress an image.
    #[error("failed to decompress an image: {0}")]
    SuperDecompressionError(String),
    /// Invalid data.
    #[error("invalid data: {0}")]
    InvalidData(String),
    /// Transcode error.
    #[error("transcode error: {0}")]
    TranscodeError(String),
    /// Format requires transcoding.
    #[error("format requires transcoding: {0:?}")]
    FormatRequiresTranscodingError(TranscodeFormat),
    /// Only cubemaps with six faces are supported.
    #[error("only cubemaps with six faces are supported")]
    IncompleteCubemap,
}

/// The type of a raw image buffer.
#[derive(Debug)]
pub enum ImageType<'a> {
    /// The mime type of an image, for example `"image/png"`.
    MimeType(&'a str),

View on GitHub (pinned to 221e52ae32)

Solutions

  1. Pass ImageType::Format(ImageFormat::Png) (or whichever format the bytes really are) instead of a mime string — it bypasses the mapping entirely.
  2. Pre-check with ImageFormat::from_mime_type(mime).is_some() and fall back to sniffing bytes via image::guess_format.
  3. Enable the matching cargo feature on bevy/bevy_image (tiff, webp, bmp, exr, hdr, dds, ktx2, basis-universal, ...).
  4. Fix the mime string to the canonical form (image/jpeg not image/jpg; image/vnd-ms.dds not image/dds).

Example fix

// before
let image = Image::from_buffer(&bytes, ImageType::MimeType("image/jpg"), ...); // Err(InvalidImageMimeType)

// after — be explicit about the format instead of the mime
let image = Image::from_buffer(&bytes, ImageType::Format(ImageFormat::Jpeg), ...);
Defensive patterns

Strategy: validation

Validate before calling

// resolve the mime to a concrete format before building ImageType
let fmt = ImageFormat::from_mime_type(mime)
    .unwrap_or_else(|| sniff_or_default(&bytes));
let image = Image::from_buffer(&bytes, ImageType::Format(fmt), formats, true, sampler, usage)?;

Type guard

fn mime_supported(mime: &str) -> bool {
    ImageFormat::from_mime_type(mime).is_some()
}

Try / catch

match Image::from_buffer(&bytes, ImageType::MimeType(mime), formats, true, sampler, usage) {
    Err(TextureError::InvalidImageMimeType(bad)) => {
        warn!("unknown mime {bad:?}; falling back to format sniffing");
        let fmt = image::guess_format(&bytes).ok().and_then(ImageFormat::from_image_crate_format);
        // retry with ImageType::Format(fmt) ...
    }
    result => result?,
}

Prevention

When it happens

Trigger: Calling Image::from_buffer with ImageType::MimeType("image/tiff") when bevy_image's tiff feature is off, or any unrecognized mime like "image/avif"; feeding a content-type header from a network download straight into ImageType::MimeType.

Common situations: Downloading images at runtime and passing the HTTP Content-Type as the image type; builds that trimmed bevy's default features (only png/qoi variants enabled) but still receive jpeg/webp mimes; typos like "image/jpg" (the canonical string is "image/jpeg").

Related errors


AI-assisted analysis of bevyengine/bevy@221e52ae32 (2026-08-20). Data as JSON: /api/errors/5b064e6f7f74e861. Report an issue: GitHub.