# Error 401 unauthorized

**URL:** <https://discuss.huggingface.co/t/error-401-unauthorized/173092>\
**Category:** Beginners\
**Created:** [February 4, 2026, 4:43pm UTC](https://discuss.huggingface.co/t/error-401-unauthorized/173092 "2026-02-04T16:43:02Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![John6666](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/john6666/32/27664_2.png) [@John6666](https://discuss.huggingface.co/u/John6666)\
**Post date:** [February 5, 2026, 2:05am UTC](https://discuss.huggingface.co/t/error-401-unauthorized/173092/2 "2026-02-05T02:05:56Z")

</div>

Hmm… I’m not familiar with Kotlin, but the cause might be related to header issues.

* * *

## What’s going on (most likely)

### 1) You’re hitting a **gated** Gemma repo

The actual LiteRT LM repo currently shown for Gemma 3n is `google/gemma-3n-E4B-it-litert-lm` and it is explicitly marked **Gated model** : “You can list files but not access them,” and you must **review and agree to Google’s usage license** while logged in. ([Hugging Face](https://huggingface.co/google/gemma-3n-E4B-it-litert-lm/tree/main "google/gemma-3n-E4B-it-litert-lm at main"))

If the Hugging Face account that created your token has **not** accepted those terms (or you accepted with a different account), Hugging Face will keep returning `401 Unauthorized` for file downloads. ([Hugging Face](https://huggingface.co/google/gemma-3n-E4B-it-litert-lm/tree/main "google/gemma-3n-E4B-it-litert-lm at main"))

### 2) Your Kotlin “plugin” doesn’t actually add headers

Your snippet defines `userAgent` and `hfToken`, but it does not hook into the request pipeline to append headers. In Ktor, you must use something like `onRequest { request, _ -> request.headers.append(...) }` (or use `defaultRequest`, or the `Auth` plugin). ([Ktor Framework](https://ktor.io/docs/client-custom-plugins.html "Custom client plugins | Ktor Documentation"))

So your requests may be going out **without** `Authorization: Bearer …`, which will always produce `401` on gated content.

### 3) You may be using a `blob` URL (viewer) instead of a `resolve` URL (raw download)

The Gemma repo README includes a `blob` link for the `.litertlm` file (that’s the web viewer URL). ([Hugging Face](https://huggingface.co/google/gemma-3n-E4B-it-litert-lm/resolve/main/README.md?download=true "23.6 kB"))  
Programmatic downloads should use the raw file endpoint pattern (`.../resolve/...`), which Hugging Face also uses as the canonical download form. ([Hugging Face](https://huggingface.co/google/gemma-3n-E4B-it-litert-lm/resolve/main/README.md?download=true "23.6 kB"))

### 4) Ktor can wait for a 401 challenge before sending credentials (unless configured)

Ktor’s Bearer auth docs explicitly describe an optional `sendWithoutRequest { ... }` to send credentials **without waiting** for a 401 response. ([Ktor Framework](https://ktor.io/docs/client-bearer-auth.html "Bearer authentication in Ktor Client | Ktor Documentation"))  
This matters when you want the Authorization header on the **first** request (common with file downloads and redirects).

* * *

## The “background” in one paragraph

Hugging Face model downloads are plain HTTP requests. For public models you can fetch files anonymously. For **private or gated** repos, Hugging Face checks (1) that the request is authenticated with a valid token and (2) that the token’s user has been granted access / accepted terms. Gemma repos are commonly gated, and the Gemma 3n LiteRT LM page explicitly requires accepting Google’s license before file access works. ([Hugging Face](https://huggingface.co/google/gemma-3n-E4B-it-litert-lm/tree/main "google/gemma-3n-E4B-it-litert-lm at main"))

* * *

## What to do for your case (recommended order)

### Step 1 — Ensure you’re using the correct repo + you accepted the gate **with the same account as the token**

Open the Gemma 3n LiteRT LM repo page while logged in and complete the “review and agree” flow. The page states requests are processed immediately. ([Hugging Face](https://huggingface.co/google/gemma-3n-E4B-it-litert-lm/tree/main "google/gemma-3n-E4B-it-litert-lm at main"))

> If your URL is `...gemma-3n-4B-it-lite-rt-lm...`, that looks like a naming mismatch. The repo currently shown is `...gemma-3n-E4B-it-litert-lm...` (note `E4B` and `litert`). ([Hugging Face](https://huggingface.co/google/gemma-3n-E4B-it-litert-lm/tree/main "google/gemma-3n-E4B-it-litert-lm at main"))

### Step 2 — Verify the token is valid (quick sanity check)

Hugging Face staff/community commonly use `api/whoami-v2` to validate tokens. ([Hugging Face Forums](https://discuss.huggingface.co/t/validating-hugging-face-api-token/45392 "Validating Hugging Face API Token - Beginners"))

```bash
curl -sS https://huggingface.co/api/whoami-v2 \
  -H "Authorization: Bearer $HF_TOKEN"

```

- If this returns 401 → token not being sent / wrong token / token revoked.
- If this succeeds → token is valid; focus on gating acceptance + URL + Ktor header injection.

### Step 3 — Use a raw download URL (`resolve`, not `blob`)

The repo lists `gemma-3n-E4B-it-int4.litertlm` in “Files and versions.” ([Hugging Face](https://huggingface.co/google/gemma-3n-E4B-it-litert-lm/tree/main "google/gemma-3n-E4B-it-litert-lm at main"))  
Use:

```plaintext
https://huggingface.co/google/gemma-3n-E4B-it-litert-lm/resolve/main/gemma-3n-E4B-it-int4.litertlm

```

(If you copied a link from the README, it’s a `blob` viewer link. ([Hugging Face](https://huggingface.co/google/gemma-3n-E4B-it-litert-lm/resolve/main/README.md?download=true "23.6 kB")))

### Step 4 — Fix your Ktor client so the Authorization header is actually attached

#### Option A (simplest): `defaultRequest { bearerAuth(...) }`

Ktor provides `bearerAuth(token)` which appends the `Authorization: Bearer ...` header. ([Ktor API](https://api.ktor.io/ktor-client-core/io.ktor.client.request/bearer-auth.html "bearerAuth"))

```kotlin
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.defaultRequest
import io.ktor.client.request.*
import io.ktor.http.*

val client = HttpClient(CIO) {
  defaultRequest {
    header(HttpHeaders.UserAgent, "MyApp/1.0")
    bearerAuth(hfToken) // adds Authorization: Bearer <token>
  }
}

```

This avoids the “plugin that doesn’t hook anything” problem.

#### Option B (more robust): use Ktor `Auth { bearer { … } }` and send token preemptively

Ktor’s bearer auth docs show how to configure tokens and `sendWithoutRequest`. ([Ktor Framework](https://ktor.io/docs/client-bearer-auth.html "Bearer authentication in Ktor Client | Ktor Documentation"))

```kotlin
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.auth.*
import io.ktor.client.plugins.auth.providers.*
import io.ktor.http.*

val client = HttpClient(CIO) {
  install(Auth) {
    bearer {
      loadTokens { BearerTokens(hfToken, "") }
      sendWithoutRequest { req -> req.url.host == "huggingface.co" }
    }
  }
}

```

### Step 5 — Confirm token permissions/scope

If you’re using a **fine-grained** token, ensure it includes read access to the specific repo/org. Hugging Face documents fine-grained tokens as resource-scoped. ([Hugging Face](https://huggingface.co/docs/hub/en/security-tokens "User access tokens"))

* * *

## If it still fails after all of the above

1. Try downloading a **public** file from Hugging Face with the same client.  
If even public downloads 401, you likely have a token/header injection issue.

2. If `whoami-v2` succeeds but **all** downloads fail with “Invalid credentials…” or similar, there have been user reports of account/token backend issues (rare, but real). ([Hugging Face Forums](https://discuss.huggingface.co/t/account-issue-new-api-tokens-all-fail-with-401-unauthorized-error/158452 "New API Tokens all fail with 401 Unauthorized Error"))

* * *

## Why the “accidental request” didn’t really “cause” it

A single bad download request doesn’t typically change server-side authorization state. What it _does_ do is reveal that the target repo is gated and/or your client isn’t attaching auth correctly—both of which deterministically produce `401`. The Gemma repo itself states it is gated and requires accepting conditions. ([Hugging Face](https://huggingface.co/google/gemma-3n-E4B-it-litert-lm/tree/main "google/gemma-3n-E4B-it-litert-lm at main"))

---

_[View the full topic](https://discuss.huggingface.co/t/error-401-unauthorized/173092)._
