awslabs/llrt · error · io::Error (InvalidInput)

unsupported encoding

Error message

unsupported encoding: {}

What it means

This error is returned by StreamingDecompressor::new in llrt_compression when the Content-Encoding string is not a recognized encoding. Recognized values include 'gzip', 'deflate', 'br' (depending on enabled feature flags), '' and 'identity'; anything else produces an io::Error of kind InvalidInput. The format placeholder carries the offending encoding name.

Solutions

  1. Normalize the encoding string (lowercase, trim) before passing it in.
  2. Handle 'identity'/'' by skipping decompression instead of constructing a decompressor.
  3. Enable the matching cargo feature (e.g. brotli) if 'br' support was compiled out.
  4. Add an explicit feature-detection step that rejects unknown encodings upstream with a clear message.

Example fix

// before
let stream = StreamingDecompressor::new(encoding)?; // encoding = "zstd"
// after
match encoding {
  "" | "identity" => stream,
  "gzip" | "deflate" | "br" => StreamingDecompressor::new(encoding)?,
  other => return Err(unsupported(other)),
}
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = ['gzip', 'deflate', 'br', '', 'identity'];
const enc = (encoding ?? '').toLowerCase().trim();
if (!SUPPORTED.includes(enc)) throw new Error('unsupported encoding: ' + enc);

Type guard

function isSupportedEncoding(e) {
  return ['gzip', 'deflate', 'br', '', 'identity'].includes(String(e).toLowerCase().trim());
}

Try / catch

match StreamingDecompressor::new(enc) {
    Ok(s) => s,
    Err(e) if e.kind() == io::ErrorKind::InvalidInput => pass_through_identity(),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Constructing a streaming decompressor with an encoding string such as 'zstd', 'compress', 'x-gzip', or a misspelled/mixed-case value like 'GZIP' that is not handled by the match.

Common situations: Servers returning unusual Content-Encoding headers (zstd, br+gzip), proxies adding encodings this build has no feature flag for, or hand-written header parsing that passes the raw header through without normalization.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.


AI-assisted analysis of awslabs/llrt@742fc00b82 (2026-09-12). Data as JSON: /api/errors/db115849f59f2621. Report an issue: GitHub.

Appendix: source

Thrown at libs/llrt_compression/src/streaming.rs:39

impl StreamingDecoder {
    pub fn new(encoding: &str) -> io::Result<Self> {
        match encoding {
            #[cfg(any(feature = "flate2-c", feature = "flate2-rust"))]
            "gzip" => Ok(Self::Gzip(flate2::write::GzDecoder::new(Vec::new()))),
            #[cfg(any(feature = "flate2-c", feature = "flate2-rust"))]
            "deflate" => Ok(Self::Deflate(flate2::write::ZlibDecoder::new(Vec::new()))),
            #[cfg(any(feature = "zstd-c", feature = "zstd-rust"))]
            "zstd" => Ok(Self::Zstd(zstd::stream::write::Decoder::new(Vec::new())?)),
            #[cfg(feature = "brotli-c")]
            "br" => Ok(Self::Brotli(brotlic::DecompressorWriter::new(Vec::new()))),
            #[cfg(all(not(feature = "brotli-c"), feature = "brotli-rust"))]
            "br" => Ok(Self::Brotli(brotlic::DecompressorWriter::new(
                Vec::new(),
                8_096,
            ))),
            "" | "identity" => Ok(Self::Identity),
            _ => Err(io::Error::new(
                io::ErrorKind::InvalidInput,
                format!("unsupported encoding: {}", encoding),
            )),
        }
    }

    /// Decompress a chunk of data, returning the decompressed output
    pub fn decompress_chunk(&mut self, input: &[u8]) -> io::Result<Vec<u8>> {
        match self {
            Self::Identity => Ok(input.to_vec()),
            #[cfg(any(feature = "flate2-c", feature = "flate2-rust"))]
            Self::Gzip(decoder) => {
                decoder.write_all(input)?;
                decoder.flush()?;
                Ok(std::mem::take(decoder.get_mut()))
            },
            #[cfg(any(feature = "flate2-c", feature = "flate2-rust"))]
            Self::Deflate(decoder) => {

View on GitHub (pinned to 742fc00b82)