Quick fix
# One shot: verify remote existence with a manifest query, then pull a concrete tag (don't bet on latest)
docker manifest inspect alpine:3.20 && docker pull alpine:3.20
What you will run into
docker pull some/image:latest (or running a non-existent image) fails with Error response from daemon: manifest for some/image:latest not found: manifest unknown.
"Image does not exist" has four common truths: typo in the repository name, the tag does not exist, private registry not logged in, or the author deleted/retagged the image.
One more trap: China mirror accelerators can rewrite this error as 403 (below) — misreading it wastes time.
Why this happens
docker pull works like this: CLI → registry manifest API (/v2/<repo>/manifests/<tag>) → download layers only after the manifest is returned. A 404 on the manifest query = the daemon reports manifest for xxx not found.
latest is not a magic value, just a default tag: if the author never pushes latest, only concrete version tags exist; deleted/private images also 404.
An image = manifest (the list describing layers and config) + layer blobs. Pull step 1 is only the manifest query; a 404 there directly means "this repo+tag combination does not exist on the registry".
The daemon wording is fixed as manifest for <image>:<tag> not found: manifest unknown (Docker Hub official form).
China mirror accelerators (registry-mirrors in daemon.json) are "proxy registries": reproduced locally (daocloud mirror), a non-existent tag returns 403 Forbidden instead of 404/manifest unknown — the mirror masks the upstream 404 with its own status code;
that is mirror behavior, not your configuration.
Deterministic takeaway: manifest unknown/not found = the combination really does not exist on the registry — check the repository spelling, verify the tag exists (docker manifest inspect or the registry web page), then consider docker login for private repos;
403 Forbidden from https://<mirror>/v2/... while direct Docker Hub works = mirror behavior — switch mirrors or check the upstream repository page.
Step by step
1. Confirm spelling and tag — Must do
docker manifest inspect <repo>:<tag> # not found = really absent remotely
docker search <repo> # confirm the repository spelling
2. Branch by scenario — By scenario
- Typo in the repository name → copy the exact name from Docker Hub / the source repo page;
- Only version tags, no latest → write the version explicitly:
docker pull redis:7-alpine; - Private registry →
docker login <registry>first, then pull; - Image deleted/migrated (e.g. moved from Docker Hub to ghcr.io) → use the new address.
3. China mirror 403 variant — By diagnosis
On unexpected status from HEAD request to https://<mirror>/v2/... 403 Forbidden: run docker info to see the current Registry Mirrors and open the upstream repository page to confirm the tag exists;
the mirror masks upstream 404 as 403, so switching mirrors (edit registry-mirrors in /etc/docker/daemon.json) usually reveals the true status.
How to confirm it works
docker manifest inspect <repo>:<tag> returns a JSON manifest; docker pull <repo>:<tag> downloads the layers normally.
Other environments
| Environment | Note |
|---|---|
| Docker Hub direct | manifest for ... not found: manifest unknown |
| China mirror accelerator | May become 403 Forbidden (daocloud reproduced) |
| Private registry | Not logged in usually gives pull access denied; login fixes it |
| Multi-arch images | Missing arch gives no matching manifest for linux/arm64; pick the arch with --platform |
Symptom
# Standard form (Docker Hub direct)
Error response from daemon: manifest for some/image:latest not found: manifest unknown
# Local reproduction (daocloud mirror, 2026-08-31)
Error response from daemon: unknown: failed to resolve reference "docker.io/library/alpine:definitely-no-tag-xyz":
unexpected status from HEAD request to https://docker.m.daocloud.io/v2/library/alpine/manifests/definitely-no-tag-xyz?ns=docker.io: 403 Forbidden
Signature: the error carries the full "repo:tag" reference; manifest ... not found = the combination is absent on the registry; a mirror domain + 403 = the accelerator rewrote the upstream 404.
Cause
Pull step 1 queries the manifest API; 404 → the daemon reports manifest not found. latest is a default tag, not a guarantee; deleted/renamed/private/typo images all look like not found. Mirror accelerators are a proxy layer and rewrite the upstream 404 into their own status code (403 reproduced); the tell is the mirror domain in the error URL.
Solution
docker manifest inspectto confirm remote existence;- Fix spelling, use a concrete version tag,
docker loginfor private repos, switch addresses for deleted/migrated images; - Mirror 403 variant = switch mirrors or verify against the upstream directly.
Verification Evidence
- Local reproduction (2026-08-31, WSL Ubuntu, docker 29.1.3, daemon.json with 1panel.live + daocloud mirrors):
docker pull alpine:definitely-no-tag-xyz→ mirror 403 Forbidden (upstream 404 rewritten);docker pull ubuntu:1.0_→ same mirror 403. The standard formmanifest for ... not found: manifest unknownwas not reproducible locally (masked by the mirror); wording and mechanism verified against Docker official docs and multiple sources, and the chain reasoning follows from manifest API semantics.
Evidence details kept locally (2026-08-31)
Related canonicals
Read in order: precondition -> same root / same domain / related:
- Same root:
- Docker Hub pull failure (network-layer failures: connection reset / no such host — same symptom family, different root cause)
Applicable tools (1)
This problem is linked from the tool pages below — reachable from either side.
dockerSource & evidence
← Coding Agents & Terminal domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk