headroomlabs-ai/headroom · error · HfTokenizerError

failed to download `{repo}` from HuggingFace Hub: {source}

Error message

failed to download `{repo}` from HuggingFace Hub: {source}

What it means

The request declared 'Content-Encoding: br' (Brotli) but the optional 'brotli' package is not installed (helpers.py:2432). Like zstd, brotli is a lazy optional dependency: the proxy only needs it when a brotli-encoded body actually arrives, so the error surfaces per-request rather than at startup.

Source

Thrown at crates/headroom-core/src/tokenizer/hf_impl.rs:46

use thiserror::Error;
use tokenizers::Tokenizer as HfInner;

use super::{Backend, Tokenizer};

#[derive(Debug, Error)]
pub enum HfTokenizerError {
    /// The bytes / file did not parse as a valid HuggingFace `tokenizer.json`,
    /// or the model component referenced an unsupported algorithm.
    #[error("failed to load tokenizer for `{name}`: {source}")]
    Load {
        name: String,
        #[source]
        source: Box<dyn std::error::Error + Send + Sync>,
    },
    /// The HuggingFace Hub fetch failed: network error, 404 on the repo, or
    /// 401 on a gated model without an `HF_TOKEN`.
    #[error("failed to download `{repo}` from HuggingFace Hub: {source}")]
    Hub {
        repo: String,
        #[source]
        source: Box<dyn std::error::Error + Send + Sync>,
    },
}

/// Token counter backed by a HuggingFace `tokenizer.json`.
///
/// Cheap to clone — internally an `Arc<tokenizers::Tokenizer>`. Construct once
/// at startup, share across handlers.
#[derive(Clone)]
pub struct HfTokenizer {
    name: String,
    inner: Arc<HfInner>,
}

impl std::fmt::Debug for HfTokenizer {

View on GitHub (pinned to 322425c43b)

Solutions

  1. pip install brotli (or add the Brotli extra to your deployment deps)
  2. Disable brotli request compression in the client and use identity or gzip
  3. Catch the ValueError and map it to a 400 with a hint so callers self-correct

Example fix

# before
headers = {"Content-Encoding": "br"}
requests.post(url, data=brotli.compress(payload), headers=headers)

# after (package not installable): use identity
requests.post(url, data=payload)
Defensive patterns

Strategy: validation

Validate before calling

try:
    import brotli  # noqa: F401
    can_brotli = True
except ImportError:
    can_brotli = False
headers = {"Content-Encoding": "br"} if can_brotli else {}

Try / catch

try:
    body = await _read_request_body_bytes(request)
except ValueError as exc:
    return JSONResponse({"error": {"type": "invalid_request_error", "message": str(exc)}}, status_code=400)

Prevention

When it happens

Trigger: A client sends a body with 'Content-Encoding: br' (common from browsers and some Go/Rust HTTP clients that enable brotli by default) in an environment where 'pip install brotli' was never run.

Common situations: Slim production images without optional extras; a client library upgrade that turns on brotli request compression; testing from a browser-based tool that always sends br.

Related errors


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