vectordotdev/vector · error
max_decompressed_size_bytes already set
Error message
max_decompressed_size_bytes already set
What it means
vector-common keeps the global decompression-size cap (used by all sources/decoders to stop decompression bombs) in a std::sync::OnceLock. `set_max_decompressed_size_bytes` initializes that cap plus two derived limits and is documented to be called exactly once, before any sources start. Calling it a second time makes OnceLock::set return Err, and this expect panics with 'max_decompressed_size_bytes already set'.
Source
Thrown at lib/vector-common/src/decompression.rs:79
.saturating_div(1000)
.saturating_add(11) as usize
}
const DEFAULT_MAX_ZLIB_COMPRESSED_FRAME_SIZE_BYTES: usize =
zlib_compressed_frame_limit(DEFAULT_MAX_DECOMPRESSED_SIZE_BYTES);
const DEFAULT_MAX_ZSTD_WINDOW_LOG: Option<u32> =
zstd_window_log_max(DEFAULT_MAX_DECOMPRESSED_SIZE_BYTES);
/// Override the global decompressed payload size cap. Must be called before any sources start.
///
/// # Panics
///
/// Panics if called more than once, as the global cap may only be initialized a single time.
pub fn set_max_decompressed_size_bytes(size: usize) {
MAX_DECOMPRESSED_SIZE_BYTES
.set(size)
.expect("max_decompressed_size_bytes already set");
MAX_ZLIB_COMPRESSED_FRAME_SIZE_BYTES
.set(zlib_compressed_frame_limit(size))
.expect("max_zlib_compressed_frame_size_bytes already set");
MAX_ZSTD_WINDOW_LOG
.set(zstd_window_log_max(size))
.expect("max_zstd_window_log already set");
}
/// Returns the currently configured decompressed payload size cap.
pub fn max_decompressed_size_bytes() -> usize {
*MAX_DECOMPRESSED_SIZE_BYTES
.get()
.unwrap_or(&DEFAULT_MAX_DECOMPRESSED_SIZE_BYTES)
}
/// Returns the maximum compressed frame wire size we are willing to buffer, derived from the
/// decompressed cap plus zlib's worst-case expansion. See `zlib_compressed_frame_limit`.
pub fn max_zlib_compressed_frame_size_bytes() -> usize {View on GitHub (pinned to 3708c39b12)
Solutions
- Call set_max_decompressed_size_bytes exactly once, at process start, before spawning any sources
- Wrap the initialization in std::sync::Once or a OnceLock<()> in your own setup helper so repeat calls become no-ops
- In test suites, move the call to a shared once-per-process helper (one #[ctor] or the first line of a common fixture) instead of per-test setup
Example fix
// before: panics when setup() runs twice
fn setup(size: usize) {
vector_common::decompression::set_max_decompressed_size_bytes(size);
}
// after: idempotent
static INIT: std::sync::Once = std::sync::Once::new();
fn setup(size: usize) {
INIT.call_once(|| {
vector_common::decompression::set_max_decompressed_size_bytes(size);
});
} Defensive patterns
Strategy: validation
Validate before calling
static INIT: std::sync::Once = std::sync::Once::new();
fn init_decompression_cap(size: usize) {
INIT.call_once(|| {
vector_common::decompression::set_max_decompressed_size_bytes(size);
});
} Try / catch
let result = std::panic::catch_unwind(|| {
set_max_decompressed_size_bytes(size);
});
if result.is_err() {
// already initialized earlier in this process; safe to ignore in test harnesses
} Prevention
- Initialize the cap exactly once at process start, before any sources start (per the API docs)
- Guard the call with std::sync::Once or a OnceLock in your own setup so repeat calls are no-ops
- In cargo test suites, use one shared once-per-process fixture rather than per-test setup calls
- Note the getters return the default when unset, so you cannot reliably probe set-ness afterwards — enforce the once rule structurally instead
When it happens
Trigger: Calling vector_common::decompression::set_max_decompressed_size_bytes twice in one process — e.g. a test harness that initializes per test without a once-guard, or two embedded components (CLI flag handler plus app init) both configuring the cap.
Common situations: Embedding Vector crates as a library; integration/cargo test suites where every test calls setup; refactors that moved the init call so it now runs on both the CLI path and the library path.
Related errors
- max_zlib_compressed_frame_size_bytes already set
- max_zstd_window_log already set
- double chunk_size_events initialization
- double thread initialization
- path and query should never fail to parse
AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20).
Data as JSON: /api/errors/8e0dc7ad90d67aaf.
Report an issue: GitHub.