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
- Normalize the encoding string (lowercase, trim) before passing it in.
- Handle 'identity'/'' by skipping decompression instead of constructing a decompressor.
- Enable the matching cargo feature (e.g. brotli) if 'br' support was compiled out.
- 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
- Normalize Content-Encoding values (lowercase/trim) before use.
- Treat '' and 'identity' as no-op; skip decompressor creation.
- Verify brotli/zstd feature flags match the encodings your services emit.
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)