pola-rs/polars · error
activate 'decompress' feature
Error message
activate 'decompress' feature
What it means
try_new for a compressed reader panics when the input is zstd-compressed (or any compression other than the always-supported ones) and the 'decompress' feature is not enabled. The build lacks the decompression backends, so it cannot handle this input and deliberately aborts.
Solutions
- Enable the decompress feature: polars = { features = ["decompress"], ... }.
- Pre-decompress the file yourself (e.g. zstd -d) and feed plain bytes.
- If reading through higher-level APIs, check which feature they need (csv/json/ipc with 'decompress').
Example fix
// before
polars = { version = "0.46", features = ["csv"] }
// after
polars = { version = "0.46", features = ["csv", "decompress"] } Defensive patterns
Strategy: validation
Validate before calling
fn needs_decompress(path: &str) -> bool {
path.ends_with(".zst") || path.ends_with(".zstd")
}
assert!(!needs_decompress(path), "enable polars feature 'decompress' for zstd inputs"); Try / catch
// It's a panic; gate at startup/feature time, not at call time
#[cfg(not(feature = "polars/decompress"))]
compile_error!("this build reads compressed files; enable polars 'decompress' feature"); Prevention
- Enable the 'decompress' feature whenever inputs may be zstd-compressed
- Sniff file extensions/magic bytes before choosing a read path
- Document required polars features next to the data-ingestion code
When it happens
Trigger: Constructing CompressedReader::try_new from a buffer whose detected compression is ZSTD (or another decompress-gated codec) on a build without feature = "decompress".
Common situations: Reading .zst-compressed CSV/IPC files with default polars features; minimal Cargo feature sets that omit decompress; upgrading and forgetting to re-add the feature.
Related errors
- activate object
- activate 'timezones' feature
- could not read
- expected index type found
- failed to encode spill file for
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/157c05d941fd9db6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/polars-io/src/utils/compression.rs:108
pub fn try_new(slice: Buffer<u8>) -> PolarsResult<Self> {
let algo = SupportedCompression::check(&slice);
Ok(match algo {
None => CompressedReader::Uncompressed { slice, offset: 0 },
#[cfg(feature = "decompress")]
Some(SupportedCompression::GZIP) => {
CompressedReader::Gzip(flate2::bufread::MultiGzDecoder::new(Cursor::new(slice)))
},
#[cfg(feature = "decompress")]
Some(SupportedCompression::ZLIB) => {
CompressedReader::Zlib(flate2::bufread::ZlibDecoder::new(Cursor::new(slice)))
},
#[cfg(feature = "decompress")]
Some(SupportedCompression::ZSTD) => {
CompressedReader::Zstd(zstd::Decoder::with_buffer(Cursor::new(slice))?)
},
#[cfg(not(feature = "decompress"))]
_ => panic!("activate 'decompress' feature"),
})
}
pub fn is_compressed(&self) -> bool {
!matches!(&self, CompressedReader::Uncompressed { .. })
}
pub const fn initial_read_size() -> usize {
// We don't want to read too much at the beginning to keep decompression to a minimum if for
// example only the schema is needed or a slice op is used. Keep in sync with
// `ideal_read_size` so that `initial_read_size * N * 4 == ideal_read_size`.
32 * 1024
}
pub const fn ideal_read_size() -> usize {
// Somewhat conservative guess for L2 size, which performs the best on most machines and is
// nearly always core exclusive. The loss of going larger and accidentally hitting L3 is not
// recouped by amortizing the block processing cost even further.View on GitHub (pinned to fe841f959e)