# ControlNetModel.from\_single\_file problem

**URL:** <https://discuss.huggingface.co/t/controlnetmodel-from-single-file-problem/171434>\
**Category:** 🧨 Diffusers\
**Created:** [December 11, 2025, 2:11pm UTC](https://discuss.huggingface.co/t/controlnetmodel-from-single-file-problem/171434 "2025-12-11T14:11:02Z")\
**Posts on this page:** 1\
**Showing post:** 4

<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:** [December 12, 2025, 5:53am UTC](https://discuss.huggingface.co/t/controlnetmodel-from-single-file-problem/171434/4 "2025-12-12T05:53:44Z")

</div>

Strictly speaking, it’s not a hub bug, but a problem that occurred with the hub…?

* * *

This is not your local `.ckpt` “failing to read.” It is Diffusers trying to fetch **extra configuration from the Hub** while loading the checkpoint, and that fetch is failing because `stabilityai/stable-diffusion-2-1` is now **not publicly reachable** (removed, made private, or gated). Your traceback shows Diffusers (via `huggingface_hub`) requesting:

`https://huggingface.co/stabilityai/stable-diffusion-2-1/resolve/main/config.json`

and receiving `401 Unauthorized`.

That pattern is common with Diffusers “single file” loaders: a `.ckpt`/`.safetensors` contains **weights** , not a complete, self-describing “Diffusers config,” so Diffusers sometimes looks up a **base model repo** to reconstruct the architecture. When that repo cannot be accessed, you get a network error even though your weights are local. This exact failure mode is discussed in Diffusers issue threads where `from_single_file()` tries to download `.../resolve/main/config.json` from a base SD repo and gets 404/401. ([GitHub](https://github.com/huggingface/diffusers/issues/9208 "Cannot load most controlnet models using from\_single\_file() · Issue #9208 · huggingface/diffusers · GitHub"))

* * *

## Why Diffusers is contacting `stabilityai/stable-diffusion-2-1` at all

### 1) A checkpoint file is “just parameters”

A `.ckpt` is typically a PyTorch pickle-based checkpoint holding tensors (and sometimes other objects). It generally does **not** contain everything needed to rebuild the model class (layer counts, channel multipliers, attention dims, etc.). Diffusers therefore needs **a config** from somewhere. ([Hugging Face](https://huggingface.co/docs/diffusers/v0.20.0/en/using-diffusers/other-formats "Load different Stable Diffusion formats"))

### 2) For SD2.x ControlNet, the config is meaningfully different

Your repo `alfredplpl/ControlNetForSD2` includes a YAML config `control_picasso11_openpose.yaml` alongside the checkpoint. The YAML shows `context_dim: 1024` and an OpenCLIP text embedder, which is characteristic of SD2-style conditioning. ([Hugging Face](https://huggingface.co/alfredplpl/ControlNetForSD2/tree/main "alfredplpl/ControlNetForSD2 at main"))

So Diffusers’ loader heuristics decide “this looks like an SD2.x-derived ControlNet,” then it tries to anchor itself to the _canonical_ SD2.1 base repo (in your case `stabilityai/stable-diffusion-2-1`) to find config. That remote anchor is what’s breaking.

### 3) The base repo being “gone” is now a real-world issue

Your linked HF forum thread (Nov 14, 2025) reports that `stabilityai/stable-diffusion-2`, `stabilityai/stable-diffusion-2-1-base`, and `stabilityai/stable-diffusion-2-1` return 404 for users, with discussion that it may be retracted or made private. ([Hugging Face Forums](https://discuss.huggingface.co/t/error-404-https-huggingface-co-stabilityai-stable-diffusion-2/170425 "Error 404 https://huggingface.co/stabilityai/stable-diffusion-2 - Models - Hugging Face Forums"))  
When a repo is private or gated, clients often see 401 (Unauthorized) unless properly authenticated, and sometimes platforms intentionally blur “not found vs not allowed.” HF staff have explained 401 commonly means “not authenticated” and the model is private or doesn’t exist. ([Hugging Face Forums](https://discuss.huggingface.co/t/error-401-client-error-unauthorized-for-url/19714 "Error 401 Client Error: Unauthorized for url - Hub - Hugging Face Forums"))

* * *

## Root causes (what can produce _this exact_ 401)

You have a few plausible causes. In your case it is likely a combination of (A) and (B):

### A) The base repo is no longer publicly accessible

If `stabilityai/stable-diffusion-2-1` was removed or made private, any attempt to fetch `config.json` from it will fail. Users reported exactly this disappearance in Nov 2025. ([Hugging Face Forums](https://discuss.huggingface.co/t/error-404-https-huggingface-co-stabilityai-stable-diffusion-2/170425 "Error 404 https://huggingface.co/stabilityai/stable-diffusion-2 - Models - Hugging Face Forums"))

### B) You are not authenticated (or your script isn’t using your token)

Even if a repo exists, gated/private repos require an access token. A very common pitfall: you are logged into the website in your browser, but your Python environment is not authenticated, so the hub download gets 401. HF forum guidance explicitly ties 401 to missing auth when the model is private or missing. ([Hugging Face Forums](https://discuss.huggingface.co/t/error-401-client-error-unauthorized-for-url/19714 "Error 401 Client Error: Unauthorized for url - Hub - Hugging Face Forums"))  
There are also cases where people believe they are logged in, but environment variables or cache locations make the CLI token invisible to the runtime. ([GitHub](https://github.com/huggingface/huggingface_hub/issues/2586 "401 Client Error - Issue with logging with Huggingface CLI/code · Issue #2586 · huggingface/huggingface\_hub · GitHub"))

### C) `from_single_file()` is pulling config from the wrong place (known Diffusers behavior)

There are open/closed Diffusers issues where `ControlNetModel.from_single_file()` succeeds for some files but fails for others because it tries to fetch a base SD repo’s `config.json`. ([GitHub](https://github.com/huggingface/diffusers/issues/9208 "Cannot load most controlnet models using from\_single\_file() · Issue #9208 · huggingface/diffusers · GitHub"))  
This is not “your fault,” it is how the loader is designed when it cannot fully infer architecture from the checkpoint alone.

* * *

## Solutions that work (ordered by practicality)

### Solution 1 (best): Provide the original YAML config that ships with your checkpoint

Your ControlNet repo **already includes** `control_picasso11_openpose.yaml`. ([Hugging Face](https://huggingface.co/alfredplpl/ControlNetForSD2/tree/main "alfredplpl/ControlNetForSD2 at main"))  
If you pass that YAML to Diffusers, it does not need to fetch the base model config from `stabilityai/stable-diffusion-2-1`.

Diffusers supports an `original_config_file` argument for single-file loading in multiple contexts (maintainers explicitly recommend it for offline and single-file loads). ([GitHub](https://github.com/huggingface/diffusers/discussions/6836 "Example of loading `from\_single\_file` with `local\_files\_only=True` · huggingface diffusers · Discussion #6836 · GitHub"))

Example:

```python
# deps:
# pip install -U diffusers huggingface_hub omegaconf safetensors torch

from diffusers import ControlNetModel
import torch

controlnet = ControlNetModel.from_single_file(
    "./models/picasso11OpenPose/control_picasso11_openpose.ckpt",
    original_config_file="./models/picasso11OpenPose/control_picasso11_openpose.yaml",
    torch_dtype=torch.float16,
    local_files_only=True, # prevents surprise hub fetches
)

controlnet.save_pretrained("./controlnet_picasso11_openpose_diffusers")

```

Why this works:

- The YAML fully describes the original architecture (channels, blocks, context\_dim, etc.). ([Hugging Face](https://huggingface.co/alfredplpl/ControlNetForSD2/blob/cde03d4987b5b9126baacafb99bee0e7360425bc/control_picasso11_openpose.yaml "control\_picasso11\_openpose.yaml · alfredplpl/ControlNetForSD2 at cde03d4987b5b9126baacafb99bee0e7360425bc"))
- `local_files_only=True` ensures Diffusers won’t quietly reach for Hub files. This aligns with Diffusers maintainer guidance for offline/single-file usage. ([GitHub](https://github.com/huggingface/diffusers/discussions/6836 "Example of loading `from\_single\_file` with `local\_files\_only=True` · huggingface diffusers · Discussion #6836 · GitHub"))

If you still see a hub call after adding `original_config_file`, it usually means the loader is trying to fetch **some other component**. For `ControlNetModel` alone, it generally should not need text encoders or tokenizers, so a remaining hub fetch is a hint something is misrouted (wrong API, wrong class, or a bug).

* * *

### Solution 2 (most robust): Convert using the official conversion script

Diffusers themselves recommend converting `.ckpt` to Diffusers format using the script, and they emphasize `original_config_file` as a key argument. ([Hugging Face](https://huggingface.co/docs/diffusers/v0.20.0/en/using-diffusers/other-formats "Load different Stable Diffusion formats"))

Conceptually:

- `from_single_file()` is convenient but can be fragile with custom checkpoints.
- The conversion script is more deterministic and produces a standard Diffusers folder with `config.json`, weights, etc.

Typical flow (ControlNet conversion):

```bash
# clone diffusers
git clone https://github.com/huggingface/diffusers
cd diffusers

python scripts/convert_original_stable_diffusion_to_diffusers.py ^
  --checkpoint_path "C:\path\to\control_picasso11_openpose.ckpt" ^
  --original_config_file "C:\path\to\control_picasso11_openpose.yaml" ^
  --dump_path "C:\path\to\output\controlnet_diffusers" ^
  --controlnet

```

This is exactly the pattern the docs and forum recommend: pass `--checkpoint_path`, `--original_config_file`, and `--dump_path`, plus `--controlnet`. ([Hugging Face](https://huggingface.co/docs/diffusers/v0.20.0/en/using-diffusers/other-formats "Load different Stable Diffusion formats"))

After that:

```python
from diffusers import ControlNetModel
controlnet = ControlNetModel.from_pretrained("C:/path/to/output/controlnet_diffusers")

```

* * *

### Solution 3: Authenticate, if the base model is merely gated (not actually removed)

If `stabilityai/stable-diffusion-2-1` still exists but is gated, you need:

- access approved on the model page
- a token
- your Python environment actually using that token

A quick diagnostic is to try downloading just the config with `huggingface_hub`. If this returns 401, your runtime is not authorized:

```python
from huggingface_hub import hf_hub_download

hf_hub_download("stabilityai/stable-diffusion-2-1", "config.json")

```

Background: HF staff have repeatedly explained 401 is what you see when you are not authenticated and the model is private or missing. ([Hugging Face Forums](https://discuss.huggingface.co/t/error-401-client-error-unauthorized-for-url/19714 "Error 401 Client Error: Unauthorized for url - Hub - Hugging Face Forums"))  
And there are known cases where people “logged in” but their token is invalid/ignored due to environment/caching differences. ([GitHub](https://github.com/huggingface/huggingface_hub/issues/2586 "401 Client Error - Issue with logging with Huggingface CLI/code · Issue #2586 · huggingface/huggingface\_hub · GitHub"))

That said, your forum link suggests SD2.x repos may be gone from the Hub for many users, so authentication may not fix it. ([Hugging Face Forums](https://discuss.huggingface.co/t/error-404-https-huggingface-co-stabilityai-stable-diffusion-2/170425 "Error 404 https://huggingface.co/stabilityai/stable-diffusion-2 - Models - Hugging Face Forums"))

* * *

### Solution 4: Use a different base SD2.x repo (local or community-hosted) for inference

Important distinction:

- Converting/loading the **ControlNet weights** is one problem.
- Actually running generation requires a **base SD2.x pipeline** (UNet, VAE, text encoder).

If the official SD2.1 repos are unavailable, you need an alternative base model source (local copy you already downloaded, or another host). The forum thread even lists unofficial mirrors, but you need to handle licensing and long-term availability yourself. ([Hugging Face Forums](https://discuss.huggingface.co/t/error-404-https-huggingface-co-stabilityai-stable-diffusion-2/170425 "Error 404 https://huggingface.co/stabilityai/stable-diffusion-2 - Models - Hugging Face Forums"))

* * *

## “Same behavior on latest diffusers?”

Very likely yes, unless you change _inputs_ (provide the YAML or convert).

The latest PyPI release as of Dec 8, 2025 is `diffusers 0.36.0`. ([PyPI](https://pypi.org/project/diffusers/ "diffusers"))  
But the key problem is not “an old diffusers bug.” It is the loader’s dependency on remote config when it cannot fully resolve architecture locally. That behavior is documented and shows up in issues across versions. ([Hugging Face](https://huggingface.co/docs/diffusers/v0.20.0/en/using-diffusers/other-formats "Load different Stable Diffusion formats"))

So: upgrading alone rarely fixes “missing config.json from a base repo.” Supplying `original_config_file` or converting does.

* * *

## Similar cases online (same failure pattern, different repo IDs)

These are worth reading because they match your situation closely:

- **Diffusers #9208** : `ControlNetModel.from_single_file()` fails on some ControlNet weights because it tries to download a base SD repo `config.json` and gets 404. Same mechanism as your 401. ([GitHub](https://github.com/huggingface/diffusers/issues/9208 "Cannot load most controlnet models using from\_single\_file() · Issue #9208 · huggingface/diffusers · GitHub"))
- **Diffusers #7935** : explicit issue title about `stabilityai/stable-diffusion-2-1` “does not appear to have a file named config.json.” ([GitHub](https://github.com/huggingface/diffusers/issues/7935 "stabilityai/stable-diffusion-2-1 does not appear to have a file named config.json. · Issue #7935 · huggingface/diffusers · GitHub"))
- **HF forum (Nov 2025)**: SD2.x repos returning 404, with discussion that the models may be retracted or private. ([Hugging Face Forums](https://discuss.huggingface.co/t/error-404-https-huggingface-co-stabilityai-stable-diffusion-2/170425 "Error 404 https://huggingface.co/stabilityai/stable-diffusion-2 - Models - Hugging Face Forums"))
- **Diffusers #7209** : offline `from_single_file()` fails because additional config is needed; references `original_config_file` in code. ([GitHub](https://github.com/huggingface/diffusers/issues/7209 "HTTPSConnectionPool Error When Loading Local safetensor Model Offline with from\_single\_file function · Issue #7209 · huggingface/diffusers · GitHub"))
- **Diffusers discussion #6836** : maintainer guidance for offline `from_single_file()`, including needing `original_config_file`. ([GitHub](https://github.com/huggingface/diffusers/discussions/6836 "Example of loading `from\_single\_file` with `local\_files\_only=True` · huggingface diffusers · Discussion #6836 · GitHub"))

* * *

## Good references: papers, guides, and “how-to” material (relevant to your case)

### Core papers (background)

- **ControlNet paper** : explains why ControlNet is an adapter that reuses a base diffusion backbone. This is the conceptual reason you need the base model architecture right. ([arXiv](https://arxiv.org/abs/2302.05543 "Adding Conditional Control to Text-to-Image Diffusion Models"))
- **Latent Diffusion Models (LDM)**: the backbone concept that Stable Diffusion and many ControlNet checkpoints build on. ([arXiv](https://arxiv.org/abs/2112.10752 "High-Resolution Image Synthesis with Latent Diffusion ..."))

### Practical guides and official docs (what to do)

- **Diffusers: “Load different Stable Diffusion formats”** : recommends conversion scripts, emphasizes `.safetensors` security, and highlights `original_config_file` as critical. ([Hugging Face](https://huggingface.co/docs/diffusers/v0.20.0/en/using-diffusers/other-formats "Load different Stable Diffusion formats"))
- **HF forum: “How to convert ckpt to diffusers format”** : canonical step-by-step and the exact key flags. ([Hugging Face Forums](https://discuss.huggingface.co/t/how-to-convert-ckpt-to-diffusers-format/35635 "How to convert ckpt to diffusers format - Diffusers - Hugging Face Forums"))
- **Diffusers ControlNet docs** : pipeline usage and model structure context. ([Hugging Face](https://huggingface.co/docs/diffusers/en/api/pipelines/controlnet "ControlNet"))

### Implementation detail (why config lookups happen)

- Diffusers code contains mappings to locate canonical YAML configs and detect checkpoint types (`CONFIG_URLS`, key heuristics). This is part of how “single-file” loading decides what it is looking at. ([Hugging Face](https://huggingface.co/spaces/gokaygokay/Flux-TRELLIS/blame/28ddbec7161ccef0e36b47bc7ee0bcf100c81002/diffusers/loaders/single_file_utils.py "diffusers/loaders/single\_file\_utils.py · gokaygokay/Flux-TRELLIS at 28ddbec7161ccef0e36b47bc7ee0bcf100c81002"))

* * *

## What I would do in _your_ exact case

1. **Stop relying on `stabilityai/stable-diffusion-2-1` entirely** for conversion. Your ControlNet repo already includes the correct YAML config. ([Hugging Face](https://huggingface.co/alfredplpl/ControlNetForSD2/tree/main "alfredplpl/ControlNetForSD2 at main"))

2. Load with:

3. Save the converted model via `save_pretrained()`.

4. Separately solve the base model availability problem for inference. If official SD2.1 repos are truly gone, you need a local base model or an alternative host, and you should expect any code that hardcodes `stabilityai/stable-diffusion-2-1` to break until updated. ([Hugging Face Forums](https://discuss.huggingface.co/t/error-404-https-huggingface-co-stabilityai-stable-diffusion-2/170425 "Error 404 https://huggingface.co/stabilityai/stable-diffusion-2 - Models - Hugging Face Forums"))

* * *

## Quick summary

- Your 401 happens because `from_single_file()` is trying to download `config.json` from `stabilityai/stable-diffusion-2-1`, not because your local `.ckpt` is unreadable. ([GitHub](https://github.com/huggingface/diffusers/issues/9208 "Cannot load most controlnet models using from\_single\_file() · Issue #9208 · huggingface/diffusers · GitHub"))
- SD2.x repos appear to be unavailable on the Hub for many users as of Nov 2025. ([Hugging Face Forums](https://discuss.huggingface.co/t/error-404-https-huggingface-co-stabilityai-stable-diffusion-2/170425 "Error 404 https://huggingface.co/stabilityai/stable-diffusion-2 - Models - Hugging Face Forums"))
- Fix it by supplying the local YAML config (`original_config_file=...yaml`) or converting with the official script. ([Hugging Face](https://huggingface.co/docs/diffusers/v0.20.0/en/using-diffusers/other-formats "Load different Stable Diffusion formats"))
- Upgrading Diffusers alone usually does not help because the failure is triggered by a missing/inaccessible remote dependency. ([PyPI](https://pypi.org/project/diffusers/ "diffusers"))

---

_[View the full topic](https://discuss.huggingface.co/t/controlnetmodel-from-single-file-problem/171434)._
