The 'manifest unknown' error occurs when Docker cannot find the image manifest in the registry. This typically happens due to an incorrect image name or tag, the tag not existing in the repository, or architecture incompatibility issues.
This error indicates that Docker was unable to locate the manifest file for the image you're trying to pull. A manifest is a JSON file that contains metadata about an image, including its layers, tags, and versioning information. When Docker cannot find this manifest, it cannot proceed with downloading the image. The error typically appears in one of these forms: - `manifest unknown: manifest unknown` - `manifest for <image>:<tag> not found: manifest unknown` - `Error response from daemon: manifest unknown` Docker uses the manifest to understand what layers need to be downloaded and how to assemble them into a working container image. Without it, the pull operation fails immediately. This error is most commonly seen when: 1. **The tag doesn't exist** - You may be requesting a tag that was never pushed to the registry 2. **Using 'latest' when it doesn't exist** - Not all images have a 'latest' tag 3. **Typo in image name or tag** - Small spelling errors prevent matching 4. **Image was deleted** - The repository or specific tag may have been removed 5. **Registry issues** - Private registry corruption or authentication problems
First, confirm that the image and tag you're trying to pull actually exist.
# Check Docker Hub directly
# Visit: https://hub.docker.com/_/<image>/tags
# For example: https://hub.docker.com/_/nginx/tags
# Or use the Docker Hub API to check available tags
curl -s "https://hub.docker.com/v2/repositories/library/nginx/tags?page_size=10" | jq '.results[].name'Common naming mistakes to check for:
- ubuntu:20.4 should be ubuntu:20.04
- mongodb should be mongo
- postgress should be postgres
- jenkins is deprecated, use jenkins/jenkins:lts
If you're unsure of the exact tag, browse the repository on Docker Hub to see what's available.
Many images don't have a 'latest' tag, or it may not be kept up to date. Always use a specific version tag:
# Instead of (may fail)
docker pull kibana:latest
# Use a specific version
docker pull kibana:8.12.0
# For multi-service stacks, specify versions in docker-compose.yml
services:
elasticsearch:
image: elasticsearch:8.12.0
kibana:
image: kibana:8.12.0Using specific version tags also improves reproducibility and avoids unexpected changes when images are updated.
Some popular images have been deprecated in favor of new repositories:
# Jenkins - old (deprecated)
docker pull jenkins:latest # Will fail
# Jenkins - new (correct)
docker pull jenkins/jenkins:lts
# Some images have moved to different organizations
docker pull mongo:latest # Official MongoDB image
docker pull bitnami/mongodb # Bitnami variantCheck the Docker Hub page for any deprecation notices or pointers to new repository locations.
If you're on an ARM-based system (like Apple Silicon Mac or Raspberry Pi), some images may not have ARM variants:
# Force pulling for a specific architecture
docker pull --platform=linux/amd64 myimage:tag
# Check what architectures an image supports
docker manifest inspect nginx:latest | jq '.manifests[].platform'Note: Running x86 images on ARM via emulation will be slower but can work for development purposes.
Older Docker versions may have compatibility issues with newer registry manifest formats:
# Check your current Docker version
docker version
# Update Docker (Ubuntu/Debian)
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# Update Docker (macOS with Homebrew)
brew upgrade docker
# Or update Docker Desktop via the applicationEnsure both the Docker client and daemon are updated, especially in environments where they might be on different machines.
Sometimes cached metadata can cause issues. Clear it and try again:
# Remove unused data
docker system prune
# Remove dangling images specifically
docker image prune
# Force re-pull by removing any existing image first
docker rmi myimage:tag 2>/dev/null; docker pull myimage:tagThis ensures Docker fetches fresh manifest data from the registry.
If using a private registry that had certificate changes or was migrated:
# Log out and log back in
docker logout myregistry.example.com
docker login myregistry.example.com
# If you have access to the source image, re-push it
docker tag localimage:tag myregistry.example.com/myimage:tag
docker push myregistry.example.com/myimage:tagRe-pushing recreates the manifest in the registry, which can fix corruption issues.
GitHub's legacy Docker package registry (docker.pkg.github.com) is deprecated and doesn't support the manifest endpoint properly. Migrate to GitHub Container Registry:
# Old (deprecated - may cause manifest errors)
docker pull docker.pkg.github.com/owner/repo/image:tag
# New (correct)
docker pull ghcr.io/owner/image:tag
# Login to GitHub Container Registry
echo $GITHUB_PAT | docker login ghcr.io -u USERNAME --password-stdinUpdate your CI/CD pipelines and Dockerfiles to use the ghcr.io format.
### Understanding Docker Manifests
A Docker image manifest is a JSON document that describes:
- The image's content-addressable layers
- Platform compatibility (OS, architecture)
- Configuration metadata
Manifests can be single-platform or multi-platform (manifest lists). When you pull an image, Docker:
1. Requests the manifest from the registry
2. Determines which layers to download based on your platform
3. Downloads and assembles the layers
You can inspect manifests directly:
# View manifest for an image
docker manifest inspect nginx:latest
# Create multi-platform manifests
docker manifest create myrepo/myimage:tag \
myrepo/myimage:tag-amd64 \
myrepo/myimage:tag-arm64### Registry API Debugging
For deeper troubleshooting, you can query the registry API directly:
# Get an auth token for Docker Hub
TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/nginx:pull" | jq -r .token)
# List tags
curl -s -H "Authorization: Bearer $TOKEN" \
"https://registry-1.docker.io/v2/library/nginx/tags/list" | jq
# Get manifest
curl -s -H "Authorization: Bearer $TOKEN" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
"https://registry-1.docker.io/v2/library/nginx/manifests/latest"### OCI vs Docker Manifest Formats
Registries support different manifest formats:
- Docker V2 Schema 2: application/vnd.docker.distribution.manifest.v2+json
- OCI: application/vnd.oci.image.manifest.v1+json
Older Docker clients might not support OCI manifests. Ensure compatibility by updating Docker or by pushing images with compatible manifest formats.
### Private Registry Troubleshooting
If your private registry returns "manifest unknown" after working previously:
1. Check registry logs for detailed error messages
2. Verify storage backend is accessible (S3, filesystem, etc.)
3. Run garbage collection carefully - improper GC can orphan manifests
4. Check registry version - upgrade if using an old version
# Check registry health
curl -s https://myregistry:5000/v2/ | jq
# List repositories
curl -s https://myregistry:5000/v2/_catalog | jqimage operating system "linux" cannot be used on this platform
How to fix 'image operating system linux cannot be used on this platform' in Docker
cannot open '/etc/passwd': Permission denied
How to fix 'cannot open: Permission denied' in Docker
Error response from daemon: failed to create the ipvlan port
How to fix 'failed to create the ipvlan port' in Docker
toomanyrequests: Rate exceeded for anonymous users
How to fix 'Rate exceeded for anonymous users' in Docker Hub
yaml: line X: found character that cannot start any token
How to fix 'found character that cannot start any token' in Docker Compose