unslothai/unsloth · critical · HTTPException

{model!r} is flagged as unsafe by Hugging Face's security sc

Error message

{model!r} is flagged as unsafe by Hugging Face's security scan and cannot be used as the embedding model.

What it means

HTTP 403 security refusal from the embedding-model endpoint when Hugging Face's security scan flags the requested model as unsafe (malware/unsafe pickle reports). This branch is non-forceable by design: the model is rejected regardless of force or cache state, because loading it would execute untrusted pickle payloads. The detail names the offending {model!r}.

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

  1. Choose a different, safe-flagged embedding model (current safetensors sentence-transformers releases).
  2. If you believe the flag is wrong, report to Hugging Face and wait for the scan status to clear — the server will not load it meanwhile.
  3. Never try to work around by loading the model outside this endpoint; the refusal reflects a real code-execution risk.

Example fix

# before
PUT /settings/embedding-model {"model": "user/flagged-model"}  # 403 unsafe

# after
PUT /settings/embedding-model {"model": "sentence-transformers/all-MiniLM-L6-v2"}
Defensive patterns

Strategy: validation

Validate before calling

const scan = await fetch(`https://huggingface.co/api/models/${model}`).then(r => r.json());
if (scan.unsafe) throw new Error(`${model} is flagged unsafe by HF; pick another model`);
await api.put('/settings/embedding-model', { model });

Type guard

function isHfSafe(modelInfo: { unsafe?: boolean } | null): boolean {
  return !!modelInfo && modelInfo.unsafe !== true;
}

Try / catch

try { await api.put('/settings/embedding-model', { model }); }
catch (e) {
  if (e.status === 403 && /unsafe/i.test(e.detail)) { blockModelPermanently(model); return; }
  throw e;
}

Prevention

When it happens

Trigger: PUT the embedding-model setting to a repo that carries HF's 'unsafe' scan badge (typically pickle-based models reported for malicious code); can also fire for a model flagged after you first cached it, since the check consults the scan status rather than only local files.

Common situations: Copy-pasting an old tutorial's embedding model id that has since been flagged; typo-squatting or re-uploaded malicious repos; supply-chain review catching a previously fine model now flagged.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/8f540903bb570a0d. Report an issue: GitHub.