vectordotdev/vector · error

max_zstd_window_log already set

Error message

max_zstd_window_log already set

What it means

The third and final OnceLock initialized by set_max_decompressed_size_bytes holds the zstd window-log maximum derived from the decompressed cap. This expect is on that cell. Via the public API it is unreachable on a double call because the first cell's expect (error 117) panics earlier; it exists to guard the internal invariant that all three cells are initialized together, exactly once.

Source

Thrown at lib/vector-common/src/decompression.rs:85

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)
}

/// Smallest zstd `window_log_max` capable of representing `max_decompressed_size` bytes.

View on GitHub (pinned to 3708c39b12)

Solutions

  1. Apply the once-only initialization fix described for error 117
  2. If this exact line fires, report it upstream — it indicates divergent internal initialization of the three cells

Example fix

// before
set_max_decompressed_size_bytes(a);
set_max_decompressed_size_bytes(b); // panics before reaching the zstd cell

// after
static INIT: std::sync::OnceLock<()> = std::sync::OnceLock::new();
let _ = INIT.set_or_init(()); // your own once-guard around the single setter call
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

When it happens

Trigger: MAX_ZSTD_WINDOW_LOG.set() returning Err — requires the main cap and zlib limit to be set while the zstd cell is not, which the single sequential public setter cannot produce; only internal misuse or a refactor adding a divergent init path could trip it.

Common situations: None through the public API; double initialization always surfaces as the error-117 panic first.

Related errors


AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20). Data as JSON: /api/errors/a2b59ffc45ee1320. Report an issue: GitHub.