headroomlabs-ai/headroom · critical · ProxyError::CompressionStartup

compression engine startup failed: {0}

Error message

compression engine startup failed: {0}

What it means

The IntelligentContextManager (compression engine) failed to build at startup — canonically because the embedded tokenizer asset failed to initialize. By design this is fatal at boot via main, not a per-request error; if it ever escapes into the handler path it maps to 500 as a defensive measure.

Source

Thrown at crates/headroom-proxy/src/error.rs:38

    #[error("io error: {0}")]
    Io(#[from] std::io::Error),

    /// PR-A8 / P5-59: request body exceeded the configured cap. RFC 7231
    /// §6.5.11: 413 Payload Too Large. Previously surfaced as
    /// `InvalidHeader` (400) which mis-classified an oversize body as a
    /// header parse error; clients with retry-on-413 logic broke.
    #[error("request body exceeds configured limit: {0}")]
    PayloadTooLarge(String),

    /// Surfaced when `--compression` is enabled but the proxy can't
    /// build the IntelligentContextManager at startup (e.g. the
    /// embedded tokenizer asset failed to initialize). Bubbles up to
    /// `main` as a fatal startup error rather than a per-request
    /// failure — if compression is configured but the engine won't
    /// build, the operator should know immediately, not at first
    /// LLM request.
    #[error("compression engine startup failed: {0}")]
    CompressionStartup(String),
}

impl IntoResponse for ProxyError {
    fn into_response(self) -> Response {
        let (status, msg) = match &self {
            ProxyError::Upstream(e) if e.is_timeout() => (
                StatusCode::GATEWAY_TIMEOUT,
                format!("upstream timeout: {e}"),
            ),
            ProxyError::Upstream(e) if e.is_connect() => (
                StatusCode::BAD_GATEWAY,
                format!("upstream connect error: {e}"),
            ),
            ProxyError::Upstream(_) => (StatusCode::BAD_GATEWAY, self.to_string()),
            ProxyError::InvalidUpstream(_) => (StatusCode::BAD_GATEWAY, self.to_string()),
            ProxyError::InvalidHeader(_) => (StatusCode::BAD_REQUEST, self.to_string()),
            ProxyError::PayloadTooLarge(_) => (StatusCode::PAYLOAD_TOO_LARGE, self.to_string()),

View on GitHub (pinned to 322425c43b)

Solutions

  1. Treat a startup abort with this message as 'do not run without compression': either fix the asset or drop --compression.
  2. Rebuild from a clean target so the tokenizer asset is re-embedded by the current build script.
  3. Verify the release artifact integrity (checksum) if using prebuilt binaries/docker images.
  4. If embedding your own tokenizer, confirm the asset version matches the engine's expected format.
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Starting the proxy with --compression when the embedded tokenizer asset is missing/corrupt in the build (feature flags excluded it, asset registry mismatch, truncated build artifact).

Common situations: Building from source without the asset-generating feature/step; a broken release artifact or docker layer; upgrading the crate where the asset format or initialization API changed but the binary mixes old asset with new code.

Related errors


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/6de8639ff20b3938. Report an issue: GitHub.