{"record":{"id":"2b964ed7f433bd7f","repo":"headroomlabs-ai/headroom","slug":"tiktoken-encoding-encoding-name-r-previously-fai","errorCode":null,"errorMessage":"tiktoken encoding {encoding_name!r} previously failed to load","messagePattern":"tiktoken encoding (.+?) previously failed to load","errorType":"exception","errorClass":"TiktokenLoadError","httpStatus":null,"severity":"error","filePath":"headroom/tokenizers/tiktoken_counter.py","lineNumber":120,"sourceCode":"# Default encoding for unknown models\nDEFAULT_ENCODING = \"cl100k_base\"\n\n\n@lru_cache(maxsize=8)\ndef _get_encoding(encoding_name: str):\n    \"\"\"Get a tiktoken encoding, cached for performance.\n\n    Bounded by ``HEADROOM_TIKTOKEN_LOAD_TIMEOUT_SECONDS`` (default 10s): tiktoken's\n    vocab download has no network timeout, so we run the load on a worker thread\n    and raise :class:`TiktokenLoadError` if it doesn't finish in time, letting\n    callers fall back to estimation rather than hang the request (GH #956). The\n    first timed-out encoding is remembered so later calls fail fast instead of\n    re-blocking on every request.\n    \"\"\"\n    import tiktoken\n\n    if encoding_name in _load_failed:\n        raise TiktokenLoadError(f\"tiktoken encoding {encoding_name!r} previously failed to load\")\n\n    box: dict[str, Any] = {}\n\n    def _load() -> None:\n        try:\n            box[\"enc\"] = tiktoken.get_encoding(encoding_name)\n        except BaseException as exc:  # noqa: BLE001 - re-raised in the calling thread\n            box[\"err\"] = exc\n\n    worker = threading.Thread(target=_load, name=f\"tiktoken-load-{encoding_name}\", daemon=True)\n    worker.start()\n    worker.join(_load_timeout_seconds())\n\n    if worker.is_alive():\n        _load_failed.add(encoding_name)\n        logger.warning(\n            \"tiktoken encoding %r did not load within %.1fs (likely a stalled vocab \"\n            \"download); falling back to token estimation. Pre-populate TIKTOKEN_CACHE_DIR \"","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/tokenizers/tiktoken_counter.py#L102-L138","documentation":"TiktokenLoadError raised in fail-fast form: the encoding name is in the module-level _load_failed set, meaning a previous _get_encoding() call for it timed out (stalled vocab download, GH #956) and was blacklisted so every later request fails immediately instead of re-blocking the worker thread. It persists for the life of the process.","triggerScenarios":"First load of e.g. 'cl100k_base' exceeded HEADROOM_TIKTOKEN_LOAD_TIMEOUT_SECONDS (default 10s) → recorded in _load_failed; any subsequent get_encoding/counter call for that name in the same process raises immediately.","commonSituations":"A request early in the process hit a stalled download (proxy/firewall); after fixing the environment the process still refuses to load because of the in-memory blacklist; long-lived servers that never restart after one transient network failure.","solutions":["Fix the underlying load condition, then restart the process — the blacklist is memory-only and resets.","Pre-populate TIKTOKEN_CACHE_DIR (download the vocab in a build step or bake it into the image) so the load is instant and never times out.","Raise HEADROOM_TIKTOKEN_LOAD_TIMEOUT_SECONDS if your network is just slow, not blocked.","Catch TiktokenLoadError and use the estimating fallback while scheduling a process restart."],"exampleFix":"# before\n# first request timed out downloading cl100k_base; later requests:\nenc = _get_encoding(\"cl100k_base\")  # TiktokenLoadError: previously failed\n\n# after (deploy step): export TIKTOKEN_CACHE_DIR=/opt/tiktoken_cache && python -c \"import tiktoken; tiktoken.get_encoding('cl100k_base')\"\n# then restart the app process; loads hit the warm cache","handlingStrategy":"fallback","validationCode":"from headroom.tokenizers.tiktoken_counter import _load_failed, TiktokenLoadError\nif name in _load_failed:\n    use_estimator_or_restart()  # fail-fast is guaranteed for this process","typeGuard":"def tiktoken_usable(name: str) -> bool:\n    from headroom.tokenizers.tiktoken_counter import _load_failed\n    return name not in _load_failed","tryCatchPattern":"from headroom.tokenizers.tiktoken_counter import TiktokenLoadError\ntry:\n    enc = load_encoding(name)\nexcept TiktokenLoadError:\n    enc = None  # use EstimatingTokenCounter; schedule process restart after cache fix","preventionTips":["Bake a populated TIKTOKEN_CACHE_DIR into images/VMs.","Restart long-lived processes after any tiktoken load failure.","Monitor for the 'previously failed' error — it means a past timeout is still poisoning the process."],"tags":["tokenizer","tiktoken","network","timeout","caching"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}