bevyengine/bevy · error · TextureError
format requires transcoding: {0:?}
Error message
format requires transcoding: {0:?} What it means
TextureError::FormatRequiresTranscodingError(TranscodeFormat) is an internal control-flow error produced by the KTX2/DDS format mappers when the stored format has no direct wgpu equivalent and must be transcoded: KTX2 with 8-bit sRGB single/dual channels (TranscodeFormat::R8UnormSrgb / Rg8UnormSrgb, ktx2.rs:1155-1233) or 3x8-bit samples (TranscodeFormat::Rgb8, ktx2.rs:659), and DDS R8G8B8 (dds.rs:156). Both loaders catch it immediately and transcode in place (ktx2.rs:107-109, dds.rs:30-37), so through the normal ImageLoader path it is handled, not surfaced. You only observe it by calling the mapping helpers directly (ktx2_get_texture_format / dds_format_to_texture_format) or by pattern-matching TextureError exhaustively.
Source
Thrown at crates/bevy_image/src/image.rs:2314
/// 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.
///
/// # Errors
///
/// A [`TextureError`] will be returned if this image type is a MIME type or file extension for
/// an unsupported or disabled format.
pub fn to_image_format(&self) -> Result<ImageFormat, TextureError> {
match self {
ImageType::MimeType(mime_type) => ImageFormat::from_mime_type(mime_type)
.ok_or_else(|| TextureError::InvalidImageMimeType(mime_type.to_string())),
ImageType::Extension(extension) => ImageFormat::from_extension(extension)
.ok_or_else(|| TextureError::InvalidImageExtension(extension.to_string())),
ImageType::Format(format) => Ok(*format),
}
}
}
View on GitHub (pinned to 221e52ae32)
Solutions
- Prefer the public entry points (Image::from_buffer / ImageLoader) — they transcode automatically and this error never escapes.
- If you call the mappers directly, handle FormatRequiresTranscodingError like the loaders do: map R8UnormSrgb->R8Unorm, Rg8UnormSrgb->Rg8Unorm, Rgb8->Rgba8(UnormSrgb).
- Re-export the texture as RGBA8 KTX2/DDS so no transcoding is needed at load time.
Example fix
// before — calling the mapper directly on an RGB8 KTX2
let fmt = ktx2_get_texture_format(&ktx2, true)?; // Err(FormatRequiresTranscodingError(Rgb8))
// after — mirror the loader's fallback
let fmt = match ktx2_get_texture_format(&ktx2, true) {
Ok(f) => f,
Err(TextureError::FormatRequiresTranscodingError(TranscodeFormat::Rgb8)) => {
TextureFormat::Rgba8UnormSrgb // loader transcodes RGB8 into this
}
Err(e) => return Err(e),
}; Defensive patterns
Strategy: try-catch
Try / catch
let fmt = match probe_format(&ktx2) {
Ok(f) => f,
Err(TextureError::FormatRequiresTranscodingError(tf)) => {
// mirror ktx2_buffer_to_image: pick the transcoded target
match tf {
TranscodeFormat::R8UnormSrgb => TextureFormat::R8Unorm,
TranscodeFormat::Rg8UnormSrgb => TextureFormat::Rg8Unorm,
TranscodeFormat::Rgb8 => TextureFormat::Rgba8UnormSrgb,
}
}
Err(e) => return Err(e),
}; Prevention
- Use Image::from_buffer / the AssetLoader instead of format-mapping internals; they transcode transparently.
- Export KTX2/DDS as RGBA8 rather than RGB8/sRGB-single-channel to avoid the transcode path entirely.
- When matching TextureError, give this variant its own arm instead of bundling it with failure cases.
When it happens
Trigger: Directly calling ktx2_get_texture_format on a KTX2 whose samples are 3x8-bit RGB, or dds_format_to_texture_format on an R8G8B8 DDS; loading such files normally does NOT surface it because ktx2_buffer_to_image and dds_buffer_to_image intercept the variant and transcode (gamma-fix R/RG channels or expand RGB to RGBA).
Common situations: Custom tooling built on bevy_image internals that inspects KTX2 formats; matching on TextureError and wondering why this arm fires; textures exported from tools that default to RGB8 storage (e.g. plain PPM-style KTX2 conversions).
Related errors
- invalid data: {0}
- supercompression not supported: {0}
- failed to decompress an image: {0}
- transcode error: {0}
- only cubemaps with six faces are supported
AI-assisted analysis of bevyengine/bevy@221e52ae32 (2026-08-20).
Data as JSON: /api/errors/c67eea65a68e3106.
Report an issue: GitHub.