vectordotdev/vector · error
max_zlib_compressed_frame_size_bytes already set
Error message
max_zlib_compressed_frame_size_bytes already set
What it means
set_max_decompressed_size_bytes initializes three global OnceLocks in sequence: the main decompressed-size cap, then the derived zlib compressed-frame limit, then the zstd window-log max. This expect is on the second cell (the zlib frame limit). Through the public API it is unreachable on a double call, because the first cell's expect (error 117) panics before this line runs; it can only fire if internal misuse sets the cells out of order.
Source
Thrown at lib/vector-common/src/decompression.rs:82
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 {
*MAX_ZLIB_COMPRESSED_FRAME_SIZE_BYTES
.get()
.unwrap_or(&DEFAULT_MAX_ZLIB_COMPRESSED_FRAME_SIZE_BYTES)View on GitHub (pinned to 3708c39b12)
Solutions
- Apply the fix for the first cell: initialize once via a Once/OnceLock guard in your setup (see error 117)
- If this exact line ever fires, report it upstream since it implies divergent internal initialization
Example fix
// before set_max_decompressed_size_bytes(a); set_max_decompressed_size_bytes(b); // panics (first at the main cap) // after static INIT: std::sync::Once = std::sync::Once::new(); INIT.call_once(|| set_max_decompressed_size_bytes(a));
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);
});
} Prevention
- Apply the same once-only initialization guard as for the main cap cell
- Do not add new call sites for set_max_decompressed_size_bytes; route all setup through one helper
When it happens
Trigger: MAX_ZLIB_COMPRESSED_FRAME_SIZE_BYTES.set() returning Err — requires the main cap to already be set while the zlib limit is not, which the single public setter (which sets them together and panics on the first) cannot produce; only direct internal misuse or a future second setter could.
Common situations: None through the public API; a double call to set_max_decompressed_size_bytes always panics at the first expect (error 117) instead.
Related errors
- max_decompressed_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/22bd76e22207e903.
Report an issue: GitHub.