unslothai/unsloth · error · HTTPException
{model!r} has cached pickle weights that cannot be security-
Error message
{model!r} has cached pickle weights that cannot be security-scanned offline and no safetensors alternative, so it cannot be used as the embedding model. Re-download it with safetensors weights while online. What it means
HTTP 403 (hard, non-forceable security refusal) from the embedding-model endpoint when local_only_load is true and the requested model has cached pickle-format weights (.bin/.pt) with no safetensors alternative. Pickle weights cannot be security-scanned offline, so the endpoint refuses to use them as the RAG embedding model; unlike the generic verification 409, no force flag bypasses this — you must obtain safetensors weights.
Source
Thrown at studio/backend/routes/settings.py:1625
model,
hf_token = scan_token,
load_subdirs = load_subdirs,
local_only_load = local_only_load,
).blocked:
# 403, not 409: the client routes every 409 into the forceable "save anyway"
# flow, but this block is a hard, non-forceable security refusal.
if local_only_load:
detail = (
f"{model!r} has cached pickle weights that cannot be security-scanned "
"offline and no safetensors alternative, so it cannot be used as the "
"embedding model. Re-download it with safetensors weights while online."
)
else:
detail = (
f"{model!r} is flagged as unsafe by Hugging Face's security scan and "
"cannot be used as the embedding model."
)
raise HTTPException(status_code = 403, detail = detail)
if model != default_embedding_model() and not payload.force and not is_local_gguf:
from core.rag import config as rag_config
# A GGUF-named repo on the llama-server backend is loaded from its .gguf
# files, which rarely carry sentence-transformers metadata; verify the
# GGUF is available (below) rather than the ST embedding-metadata gate,
# which would wrongly 409 a valid online GGUF embedder.
gguf_named = _llama_backend_active() and rag_config._names_gguf(model)
if not gguf_named and not is_embedding_model(model, hf_token = hf_token):
# Offline, is_embedding_model can only confirm the ST layout (modules.json); a
# transformers-native embedder (e.g. gte-modernbert) is unverifiable without Hub
# metadata. If already cached and loadable, accept it rather than raising a 409 that
# online would not (ST can load any cached encoder). Uncached -> 409.
from utils.utils import hf_cache_snapshot_is_loadable
# Require a genuinely loadable cache (config + weights), not just a resolved refs/main,
# so a metadata-only partial cache still gets the forceable 409.
offline_cached = local_only_load and hf_cache_snapshot_is_loadable(model)View on GitHub (pinned to 203007d190)
Solutions
- Bring the server online once and re-download the model so safetensors weights are fetched alongside (or instead of) the pickle files.
- Or delete the pickle-only cache entry and download the repo with safetensors on a connected machine, then copy the cache over.
- Do not attempt to bypass with force:true — this branch intentionally ignores it.
- Prefer repos that publish safetensors (most current sentence-transformers models do).
Example fix
# before (offline, pickle-only cache)
PUT /settings/embedding-model {"model": "old-model-with-.bin-only"} # 403
# after (one-time online refresh)
huggingface-cli download old-model --include "*.safetensors" "*.json"
# restart offline mode; the same PUT now passes the scan gate Defensive patterns
Strategy: validation
Validate before calling
const files = await listLocalCacheFiles(model);
const hasSafetensors = files.some(f => f.endsWith('.safetensors'));
if (!hasSafetensors) throw new Error('Model lacks safetensors; refresh online before offline use');
await api.put('/settings/embedding-model', { model }); Type guard
function isOfflineSafeEmbedder(files: string[]): boolean {
return files.some(f => f.endsWith('.safetensors'));
} Try / catch
try { await api.put('/settings/embedding-model', { model }); }
catch (e) {
if (e.status === 403 && /pickle/i.test(e.detail)) { queueOnlineRedownload(model); return; } // not forceable
throw e;
} Prevention
- Standardize on safetensors releases when seeding caches for offline machines.
- Periodically refresh caches while online so pre-safetensors snapshots get updated.
- Accept that this 403 ignores force:true by design; plan provisioning around it.
When it happens
Trigger: PUT the embedding-model setting to a repo whose local cache only contains pickle weight files, while the server runs in local/offline-only load mode (no Hub access).
Common situations: Pre-2023 sentence-transformers snapshots downloaded before safetensors became standard; air-gapped machines; a cache populated by an older tool that skipped safetensors; partial downloads that kept the .bin files.
Related errors
- {model!r} is flagged as unsafe by Hugging Face's security sc
- Could not verify {model!r} as an embedding model on Hugging
- gguf_error
- Embedding model {name!r} {reason}; refusing to load. Set a d
- Model path is outside Unsloth storage
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/63ea11896cd277e1.
Report an issue: GitHub.