Fix Docker Pull Manifest Unknown Errors
Learn how to diagnose and fix docker pull manifest unknown errors by checking image references, tag existence, platform compatibility, and registry authentication.
Rao Aadil, India 9 min read
What does 'manifest unknown' actually mean?
When Docker can't pull an image, the error usually shows up as:
manifest for <image>:<tag> not found: manifest unknown: manifest unknown
The registry returned HTTP 404 for the manifest. Docker didn't find an image with the exact name and tag you requested. The registry is telling you that the manifest—the JSON document describing image layers, architecture, and configuration—does not exist.
Docker breaks an image reference like nginx:latest into three parts: registry, repository, tag. By default the registry is Docker Hub (registry-1.docker.io). The repository is the namespace and image name (e.g., library/nginx). The tag defaults to latest when you omit it. docker pull asks the registry for the manifest for that specific repository and tag. If the registry can't find it, the pull fails with manifest unknown.
Because this error comes from the registry's response, it is identical on Linux and Windows. The client operating system does not change the message.
Inspect containers, read logs, check stats, restart services and run Compose stacks, just by describing what you want.
“why does this container keep restarting”
It reads the real state of the server before it says anything, shows you the exact command, and waits for your approval. Windows and Linux, over the SSH access you already have.
Step 1: Verify the image reference
A typo in the image reference is the most common cause. Check repository and tag spelling first. Image names are case-sensitive. Official Docker Hub images live under the library namespace, which you normally omit. docker pull nginx is shorthand for docker pull library/nginx. If you type docker pull Nginx, Docker reads the repository as library/Nginx (uppercase N), and Docker Hub returns manifest unknown because that repository doesn't exist.
Also check the registry domain. With a private registry, include hostname and port: myregistry.example.com:5000/myimage:tag. If you omit the registry domain, Docker sends the request to Docker Hub by default, which is usually not what you want.
The full reference format is:
[registry]/[namespace]/[repository]:[tag]
If you're not sure whether a public repository exists on Docker Hub, use docker search:
Linux/macOS (shell):
docker search nginx
Windows (cmd or PowerShell):
docker search nginx
docker search lists repositories matching the name. It won't tell you whether a specific tag exists; that needs another check.
Step 2: Check if the tag exists with the registry API
docker manifest inspect is the quickest way to check a tag. It queries the registry's API directly. For an existing tag, it prints the manifest JSON; for a missing tag, it exits with an error.
Example:
docker manifest inspect nginx:latest
If the tag is missing, you'll see no such manifest or manifest unknown. docker manifest inspect is experimental in older Docker versions but available by default in Docker 20.10 and later, including Windows.
For more detailed checking, query the Docker Hub API to list tags for a repository. The Docker Registry HTTP API V2 has no built-in tag listing endpoint; Docker Hub offers a separate REST API. Use these commands:
Linux/macOS (shell):
curl -s "https://hub.docker.com/v2/repositories/library/nginx/tags/?page_size=100"
Windows PowerShell:
Invoke-RestMethod -Uri "https://hub.docker.com/v2/repositories/library/nginx/tags/?page_size=100"
This returns a JSON object with a results array of tag names. If your tag isn't there, it doesn't exist. For private registries, you need authentication. After docker login, docker manifest inspect uses the stored credentials. For direct API calls, add an Authorization header with a bearer token.
Step 3: Confirm your platform and architecture
A tag can exist and still fail to pull if the image has no manifest for your platform. Multi-arch images contain manifests for several architectures and operating systems. Pulling on an ARM64 Linux host when the image only has an amd64 manifest makes Docker look for a matching platform and fail with manifest unknown. Running Windows containers and trying to pull a Linux-only image fails the same way: platforms don't match.
Use docker manifest inspect and check the platforms field to see what an image supports. For example:
docker manifest inspect nginx:latest
The output for a multi-arch image includes:
{
"manifests": [
{
"digest": "sha256:...",
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"digest": "sha256:...",
"platform": {
"architecture": "arm64",
"os": "linux"
}
}
]
}
If your host's platform is not listed, the pull fails. On Windows, Docker Desktop runs either Linux containers or Windows containers. The mode determines which platform the daemon requests. To switch, right-click the Docker Desktop tray icon and select "Switch to Linux containers" or "Switch to Windows containers". You can also specify the platform explicitly when pulling, but only if the image supports it:
docker pull --platform linux/amd64 nginx:latest
This works on Linux and Windows (when Docker Desktop is in Linux container mode). It helps when you need a specific architecture. Changing daemon settings is not required for switching container modes, but if you need to, the file is /etc/docker/daemon.json on Linux and C:\ProgramData\Docker\config\daemon.json on Windows.
Step 4: Validate authentication for private registries
Private registries often return manifest unknown instead of 401 Unauthorized when you aren't authenticated or don't have access to a repository. That's intentional: the registry hides the existence of images from users who shouldn't see them.
Check whether you're logged in first:
docker login
If already logged in, the command says "Authenticating with existing credentials" or prompts again. To see which registries you have credentials for, inspect the Docker configuration file.
Linux and macOS: ~/.docker/config.json
Windows: %USERPROFILE%\.docker\config.json
Open the file in a text editor or use cat/type:
Linux/macOS:
cat ~/.docker/config.json
Windows cmd:
type %USERPROFILE%\.docker\config.json
Windows PowerShell:
Get-Content $env:USERPROFILE\.docker\config.json
Look for an auths section. If your registry isn't listed, you're not logged in. If it is listed, the credentials may be expired or lack permission for that repository. Re-authenticate:
docker login myregistry.example.com
Then run the pull again. If the image exists and you have access, it should succeed.
Step 5: Fix the pull and verify
Once you know the cause, apply the correction.
- Wrong image reference? Fix the spelling, registry domain, or namespace.
- Tag didn't exist? Pick a tag that does. Confirm with
docker manifest inspector the registry API. - Platform incompatible? Switch container mode on Windows or pull with
--platformif the image supports it. - Auth problem? Log in to the registry and confirm access.
Then run docker pull again with the corrected reference:
Linux/macOS:
docker pull nginx:1.25
Windows (cmd or PowerShell):
docker pull nginx:1.25
If you use Docker Compose, update the image: field in docker-compose.yml to the correct reference, then run:
docker compose pull
This pulls all images defined in the Compose file. For one service, use docker compose pull <service>.
For teams managing many servers, a Docker AI agent can run these same diagnostic steps across all registered hosts: verify the image reference, run docker manifest inspect or query the registry API with an approved arbitrary command, check registry credentials in config.json, and read Docker daemon logs for clues. That saves time when you have to check the same error on many machines.
How to prevent manifest unknown in the future
Pin images by digest. Instead of mutable tags, use nginx@sha256:.... Digests are immutable and always pull the exact same image. Get the digest from docker manifest inspect or from an earlier successful pull with docker inspect.
Establish a tagging policy. Every image you deploy should have a tag that will always exist. Don't retag or delete tags that are in use. Use versioned tags like v1.2.3 alongside latest, and never move a version tag.
Add a CI step to check manifest existence. Before deploying, run docker manifest inspect for the exact image and tag in CI. This catches missing tags before production. Example:
docker manifest inspect myimage:${TAG} || exit 1
If you have buildx, docker buildx imagetools inspect can also check the manifest list and platforms.
Regularly review registry credentials and access permissions. In private registries, make sure deployment system credentials have access to the necessary repositories. Rotate tokens on schedule and remove unused accounts.
Frequently asked questions
Why do I get manifest unknown when the tag clearly exists on Docker Hub?
You may be using the wrong namespace or case. Official images live under library (so nginx is library/nginx), and repository names are case-sensitive. Check for tag typos too: latest is not Latest. Verify with docker manifest inspect using the exact name.
How can I check if a tag exists before running docker pull?
Run docker manifest inspect <image>:<tag>. If it succeeds, the tag exists. For more detail, query the Docker Hub API with curl or Invoke-RestMethod and look for your tag in the results.
Does manifest unknown mean I'm not authenticated to a private registry?
It can. Private registries often return 404 instead of 401 to avoid revealing image names. If you get manifest unknown from a private registry, run docker login for that registry and try again. If it persists, check your account permissions for the repository.
Why does docker pull work on my Linux machine but not on Windows (or vice versa)?
The image may not support the Windows host's platform. Windows containers require a Windows manifest. Linux containers on Windows (via Docker Desktop) require a Linux manifest. Use docker manifest inspect to see which platforms the image supports, then switch container modes if needed.
Can I pull an image by digest to avoid the manifest unknown error?
Yes. docker pull <image>@sha256:<digest> bypasses tag resolution entirely. The digest points to a specific manifest and won't change. Obtain it from a trusted source or an earlier successful pull.