bevyengine/bevy · error · TextureError

unsupported texture format: {0}

Error message

unsupported texture format: {0}

What it means

TextureError::UnsupportedTextureFormat (the String variant on TextureError) signals a texture format the loader cannot deliver, with a different cause per site: dds.rs:41 rejects formats the GPU does not support ("Format not supported by this GPU" — checked against CompressedImageFormats built from adapter features); ktx2.rs has dozens of VkFormat/sample combinations with no mapping (e.g. "3-component formats not supported"); basis.rs:35 rejects source formats that cannot transcode to the target; image.rs:1629 and image_loader.rs:221 hit formats with no image-crate decoder or no Bevy ImageFormat equivalent. It is the general 'cannot use this format here' error of the texture import pipeline.

Source

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

    /// 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),
    /// The extension of an image file, for example `"png"`.
    Extension(&'a str),
    /// The direct format of the image
    Format(ImageFormat),
}

impl<'a> ImageType<'a> {
    /// Attempts to detect the appropriate [`ImageFormat`] for this image type.
    ///

View on GitHub (pinned to 221e52ae32)

Solutions

  1. Request the matching compression feature on the renderer (WgpuSettings.features |= Features::TEXTURE_COMPRESSION_BC / ETC2 / ASTC_LDR) so CompressedImageFormats includes your format.
  2. Ship per-platform textures: BC for desktop, ASTC/ETC2 for mobile, and pick at load time.
  3. Enable the container features on bevy/bevy_image (dds, ktx2, basis-universal) if the file never reaches its decoder.
  4. Re-export the texture as plain PNG (uncompressed Rgba8UnormSrgb), which every device accepts, accepting the memory cost.

Example fix

// before — BC dds fails on devices without BC support
let image = server.load("wall.dds"); // TextureError: unsupported texture format: Format not supported by this GPU: Bc3...

// after — request the feature and gate the asset by adapter support
let mut wgpu_settings = WgpuSettings::default();
wgpu_settings.features |= wgpu::Features::TEXTURE_COMPRESSION_BC;
// plus, at asset-selection time:
let supports_bc = compressed_formats_supports.contains(CompressedImageFormats::BC);
let path = if supports_bc { "wall_bc.dds" } else { "wall_astc.ktx2" };
Defensive patterns

Strategy: validation

Validate before calling

// verify the format is in the adapter-supported set before loading containers
let supported = CompressedImageFormats::from_features(renderer_features);
let ok = supported.supports(TextureFormat::Bc3RgbaUnormSrgb);
if !ok {
    // choose the ASTC/ETC2 variant or uncompressed fallback asset
}

Type guard

fn format_loadable(fmt: TextureFormat, supported: &CompressedImageFormats) -> bool {
    let compressed = fmt.required_features();
    compressed.is_empty() || supported.supports(fmt)
}

Try / catch

match Image::from_buffer(&bytes, ty, formats, true, sampler, usage) {
    Err(TextureError::UnsupportedTextureFormat(msg)) => {
        warn!("{msg}; using uncompressed fallback");
        Image::from_buffer(&png_bytes, ImageType::Format(ImageFormat::Png), formats, true, sampler, usage)
    }
    result => result,
}

Prevention

When it happens

Trigger: Loading a BC-compressed .dds on a GPU without TEXTURE_COMPRESSION_BC (common on Apple Silicon / mobile where only ASTC or ETC2 exist); a KTX2 with an exotic VkFormat; a Basis file whose basis_texture_format cannot transcode to the device's target format; enabling Guess-mode loading for bytes the image crate recognizes but Bevy has no ImageFormat for.

Common situations: Shipping one set of BC (Desktop) textures and running on macOS/Android; requesting adapter features in WgpuSettings that the physical device silently does not provide; disabling bevy features like dds/ktx2/basis-universal while still loading those files.

Related errors


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