# Why HuggingFace gives you a 401 or 403 on a gated repo, and how to actually fix it

> Source: https://netray.co/troubleshoot/huggingface-401-gated-repo
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: On-Prem AI Troubleshooting

## Short answer

A 401 or 403 on a gated HuggingFace repo means the request reached the Hub but was rejected for authorization, not because the model does not exist. The three real causes are: you have not accepted the model's license on the web page with the account tied to your token, the token exists but was created without read access to gated repos, or the token is valid but was never actually passed to the download call (no HF_TOKEN in the environment, no login run). Fix by accepting the license, generating a token with the right scope, and exporting it where the client library will find it.

## Error Title

401/403 Unauthorized pulling a gated model from HuggingFace

## Error Signature

OSError: You are trying to access a gated repo. Make sure to have access to it at https://huggingface.co/meta-llama/Llama-3.3-70B-Instruct

## Alternate Signatures

- requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://huggingface.co/api/models/...
- huggingface_hub.utils._errors.GatedRepoError: Access to model ... is restricted
- 403 Forbidden: Cannot access gated repo for url ...

## Category

model-loading

## Stack

- huggingface
- transformers

## Affects

Any gated or license-gated repo on huggingface.co (Llama, Gemma, some Mistral variants), transformers/huggingface_hub of any recent version

## Quick Fix

### Fastest path to a working download

**Steps:**

- Open the model page on huggingface.co while logged in and click Agree/Accept to accept the license (this is per-account, not automatic).
- Create a new access token at huggingface.co/settings/tokens with type Read (or Fine-grained with explicit access to the gated repo).
- Export it in the shell you are running from: export HF_TOKEN=hf_xxxxxxxx (or run huggingface-cli login and paste it).
- Confirm the CLI sees it: huggingface-cli whoami should print your username, not an error.
- Retry the download or from_pretrained call. If it still fails, check the token belongs to the same account that accepted the license (common with org accounts).

## Symptoms

- Download or from_pretrained call fails immediately with a 401 or 403 before any bytes are transferred
- The same script works for ungated models like a small Qwen or Mistral checkpoint but fails specifically on Llama or Gemma family repos
- huggingface-cli whoami works, but the specific repo still fails
- Error message explicitly says 'gated repo' or 'restricted' rather than 'repository not found'

## Causes

### License not accepted on the HuggingFace website for this account

**Likelihood:** most-common

**Explanation:** Gated repos require a per-account, per-model acceptance click on the web UI (sometimes with a form for organizations like Meta). Creating a token does not grant access by itself; the account itself must be separately approved or self-approved for that repo. A perfectly valid token from an account that never clicked Agree will always be rejected.

**Fix:** Log into huggingface.co with the exact account whose token you are using, open the model page, and accept the license terms. Some repos (certain Llama releases) additionally gate through a Meta approval form that can take minutes to hours to clear.

**Commands:**

- huggingface-cli whoami

### Token has no read scope for gated content, or is a write-only/fine-grained token missing repo access

**Likelihood:** common

**Explanation:** Fine-grained tokens created for a specific purpose (e.g. only inference API) do not automatically include 'Read access to contents of all public gated repos you can access'. Without that permission box checked, the token authenticates you but the Hub still refuses the specific gated download.

**Fix:** Regenerate the token as a classic Read token, or edit the fine-grained token to explicitly enable the gated-repo read permission, then re-export it.

**Commands:**

- huggingface-cli logout
- huggingface-cli login

### Token never reached the process: not exported, wrong shell, or overwritten by CI secrets

**Likelihood:** common

**Explanation:** huggingface_hub reads HF_TOKEN (or the legacy HUGGING_FACE_HUB_TOKEN) from the environment or from ~/.cache/huggingface/token written by huggingface-cli login. If you exported the token in one terminal and ran the job in another (a different shell, a systemd service, a Docker container without --env), the library falls back to anonymous access and the gated call fails.

**Fix:** Explicitly pass the token to the call (token="hf_xxx" in from_pretrained, or HF_TOKEN as a Docker/Kubernetes secret env var) instead of relying on ambient shell state, especially in containers and CI.

**Commands:**

- python -c "import os; print('HF_TOKEN' in os.environ)"
- docker run -e HF_TOKEN=$HF_TOKEN ...

### Organization SSO or org-level gating requires membership approval separate from personal account access

**Likelihood:** occasional

**Explanation:** Some enterprise or org-hosted repos require the requesting account to be an approved member of the organization on the Hub, in addition to accepting any license. A personal account that can browse the org's public page may still be rejected on gated assets until an org admin approves membership or grants the token an org-scoped permission.

**Fix:** Check the organization's member list and pending-request queue on huggingface.co, have an org admin approve access, then regenerate a token under that verified membership.

### Cached negative auth state or stale token in huggingface_hub's local cache

**Likelihood:** rare

**Explanation:** huggingface_hub caches some auth and repo metadata locally. After fixing license acceptance or token scope, a stale cached 401 response or an old token stored in ~/.cache/huggingface/token can keep failing until the cache is cleared and the client re-authenticates.

**Fix:** Delete the cached token and any partial repo metadata cache, then log in again fresh.

**Commands:**

- rm ~/.cache/huggingface/token
- huggingface-cli login

## Diagnostics

### Confirm identity

**Command:** huggingface-cli whoami

**Interpretation:** If this errors out, no token is configured at all, fix that first. If it prints a username, the token is valid for identity but may still lack gated-repo scope.

### Test raw API access to the specific repo

**Command:** curl -s -H "Authorization: Bearer $HF_TOKEN" https://huggingface.co/api/models/meta-llama/Llama-3.3-70B-Instruct

**Interpretation:** A JSON response with model metadata means access is granted. A 401 means the token itself is invalid or missing. A 403 with 'gated' in the body confirms license or membership is the blocker, not the token format.

### Check where the environment actually runs

**Command:** env | grep -i hf_token

**Interpretation:** If empty inside the container or job that fails, the token exists in your interactive shell but was never passed into the execution environment, explaining why it works manually but not in a script or pipeline.

## Prevention

Standardize on one org-approved service account token stored as a secret (Kubernetes Secret, Vault, CI secret) rather than personal tokens scattered across engineers' shells.

For air-gapped or regulated environments, mirror approved gated models into an internal artifact store after one-time authenticated download, so production nodes never need live HuggingFace credentials.

Document which accounts have accepted which model licenses so a departing employee's token revocation does not silently break a production pipeline.

Add a pre-flight check in deployment scripts that calls huggingface-cli whoami and a HEAD request to the target repo before starting a long download.

## When To Escalate

If this is blocking a regulated or air-gapped environment where individual engineers cannot hold live HuggingFace credentials at all, the fix is not a better token, it is an internal model registry: download once through an approved, audited path, verify the artifact, and serve every other environment from your own storage. That is an architecture decision, not a config fix.

## Faq

### I accepted the license, why is it still failing?

**Answer:** License acceptance can take a few minutes to propagate on HuggingFace's side, and for some Meta-gated models there is a second approval step through a separate form that is not instant. Also double check you accepted it with the same account whose token you are using; it is easy to have two browser sessions logged into different accounts.

### Does passing use_auth_token still work or do I need token now?

**Answer:** Recent huggingface_hub and transformers versions renamed the parameter to token; use_auth_token is deprecated and may emit a warning or be removed depending on version. Passing token="hf_xxx" explicitly is the more future-proof approach and also avoids ambient environment variable confusion.

### Can I download a gated model once and reuse it without a token everywhere else?

**Answer:** Yes, and for air-gapped or regulated deployments this is the recommended pattern: authenticate once from an approved workstation, download the full snapshot, verify its integrity, then copy that local directory to production and load with a local path plus HF_HUB_OFFLINE=1 so no further network or token access is needed.

### My token works in Python but not in huggingface-cli download, why?

**Answer:** Check that HF_TOKEN is exported in the exact shell invoking the CLI, not just set inside a Python script via login(token=...) which only affects that Python process's session. Environment variables and huggingface-cli login's saved token file are separate from a token passed programmatically inside one script.

## Search terms

huggingface 401 gated repo, huggingface gated repo access, GatedRepoError, huggingface 403 forbidden model, accept license huggingface, HF_TOKEN not working, huggingface-cli login token, llama gated access huggingface

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
