{"record":{"id":"8f540903bb570a0d","repo":"unslothai/unsloth","slug":"model-r-is-flagged-as-unsafe-by-hugging-face-s-s","errorCode":null,"errorMessage":"{model!r} is flagged as unsafe by Hugging Face's security scan and cannot be used as the embedding model.","messagePattern":"(.+?) is flagged as unsafe by Hugging Face's security scan and cannot be used as the embedding model\\.","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"critical","filePath":"studio/backend/routes/settings.py","lineNumber":1625,"sourceCode":"            model,\n            hf_token = scan_token,\n            load_subdirs = load_subdirs,\n            local_only_load = local_only_load,\n        ).blocked:\n            # 403, not 409: the client routes every 409 into the forceable \"save anyway\"\n            # flow, but this block is a hard, non-forceable security refusal.\n            if local_only_load:\n                detail = (\n                    f\"{model!r} has cached pickle weights that cannot be security-scanned \"\n                    \"offline and no safetensors alternative, so it cannot be used as the \"\n                    \"embedding model. Re-download it with safetensors weights while online.\"\n                )\n            else:\n                detail = (\n                    f\"{model!r} is flagged as unsafe by Hugging Face's security scan and \"\n                    \"cannot be used as the embedding model.\"\n                )\n            raise HTTPException(status_code = 403, detail = detail)\n    if model != default_embedding_model() and not payload.force and not is_local_gguf:\n        from core.rag import config as rag_config\n\n        # A GGUF-named repo on the llama-server backend is loaded from its .gguf\n        # files, which rarely carry sentence-transformers metadata; verify the\n        # GGUF is available (below) rather than the ST embedding-metadata gate,\n        # which would wrongly 409 a valid online GGUF embedder.\n        gguf_named = _llama_backend_active() and rag_config._names_gguf(model)\n        if not gguf_named and not is_embedding_model(model, hf_token = hf_token):\n            # Offline, is_embedding_model can only confirm the ST layout (modules.json); a\n            # transformers-native embedder (e.g. gte-modernbert) is unverifiable without Hub\n            # metadata. If already cached and loadable, accept it rather than raising a 409 that\n            # online would not (ST can load any cached encoder). Uncached -> 409.\n            from utils.utils import hf_cache_snapshot_is_loadable\n\n            # Require a genuinely loadable cache (config + weights), not just a resolved refs/main,\n            # so a metadata-only partial cache still gets the forceable 409.\n            offline_cached = local_only_load and hf_cache_snapshot_is_loadable(model)","sourceCodeStart":1607,"sourceCodeEnd":1643,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/settings.py#L1607-L1643","documentation":"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}.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Choose a different, safe-flagged embedding model (current safetensors sentence-transformers releases).","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.","Never try to work around by loading the model outside this endpoint; the refusal reflects a real code-execution risk."],"exampleFix":"# before\nPUT /settings/embedding-model {\"model\": \"user/flagged-model\"}  # 403 unsafe\n\n# after\nPUT /settings/embedding-model {\"model\": \"sentence-transformers/all-MiniLM-L6-v2\"}","handlingStrategy":"validation","validationCode":"const scan = await fetch(`https://huggingface.co/api/models/${model}`).then(r => r.json());\nif (scan.unsafe) throw new Error(`${model} is flagged unsafe by HF; pick another model`);\nawait api.put('/settings/embedding-model', { model });","typeGuard":"function isHfSafe(modelInfo: { unsafe?: boolean } | null): boolean {\n  return !!modelInfo && modelInfo.unsafe !== true;\n}","tryCatchPattern":"try { await api.put('/settings/embedding-model', { model }); }\ncatch (e) {\n  if (e.status === 403 && /unsafe/i.test(e.detail)) { blockModelPermanently(model); return; }\n  throw e;\n}","preventionTips":["Pin embedding models to well-known orgs (sentence-transformers, BAAI) pinned by revision.","Check the HF model page's scan badge before configuring.","Never cache-and-load flagged pickle models outside this endpoint either."],"tags":["fastapi","http-403","security","hugging-face","unsafe-model","supply-chain","embeddings"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}