skip to content

Why does docker pull fail with "no matching manifest for windows/amd64" after switching to Windows containers?

level: juniorimportance: should knowfreq 50%

answer

  1. The engine only serves one OS
  2. Check the server side, not the client
  3. docker info reports an OSType
  4. The registry picks by os and arch
  5. No windows entry in that manifest list

basics

~20 s

A Docker engine serves one container operating system at a time. Once it is switched to Windows containers it asks the registry for a windows/amd64 image, and the image you pulled publishes only Linux entries, so nothing matches.

solid answer

~50 s

That message comes from image selection, not from a broken tag. A Docker engine has a single OSType: after the switch to Windows containers the daemon reports `windows/amd64`, and every pull asks the registry for the entry matching that OS and architecture. A Linux-only image such as an nginx image serving a static Hugo site publishes `linux/amd64` and `linux/arm64` entries only, so the manifest list has nothing for `windows/amd64` and the pull is refused. A Linux image published without a manifest list fails slightly later instead, with `image operating system "linux" cannot be used on this platform`. Check `docker info --format '{{.OSType}}'` or the Server `OS/Arch` line of `docker version` to see which mode you are in. The fix is to switch the engine back to Linux containers, or to pull a Windows base image such as `mcr.microsoft.com/windows/nanoserver:ltsc2022`. There is no conversion between the two.

code

bash · 3 lines
bash
docker info --format '{{.OSType}}'
docker version --format 'server={{.Server.Os}}/{{.Server.Arch}}'
docker pull mcr.microsoft.com/windows/nanoserver:ltsc2022

go deeper

for a junior

Recall the one-line rule: an engine serves either Linux or Windows containers, and the manifest error means the image has no entry for the OS your engine is running. Know that docker info will tell you which mode you are in.

for a middle

Be ready to explain where selection happens: the daemon fetches the manifest list and matches os/architecture against its own platform, which is why a single-manifest Linux image fails at run time instead with a different message.

for a senior

Show that you treat this as a fleet layout question. Explain how you label CI agents by OSType, keep Windows workloads on dedicated hosts, and avoid Compose files that assume one engine can serve a mixed stack.

for a principal

Own the consequence for platform strategy: supporting both OS types doubles the host pool, the base-image inventory and the patching pipeline. Be able to argue when one Windows workload justifies that, and when porting it is cheaper.

## One engine serves one container OS A container is not a portable virtual machine image; it is a process that expects a particular kernel's system-call interface. A Linux image contains ELF binaries that call into a Linux kernel, and a Windows image contains PE binaries that call into the Windows kernel. Nothing in the Docker engine translates between them. That single fact is why a Docker engine has an **OSType**: the daemon is either serving Linux containers or Windows containers, never both at once. On a Windows machine, switching modes (the tray item on Docker Desktop, or a `-SwitchDaemon` style toggle on a server install) does not reconfigure one daemon so much as point your CLI at the other one. Each side keeps its own image store, its own containers, its own networks and its own volumes. That is why images and containers you were working with five minutes ago vanish from `docker images` and `docker ps -a` after a switch, and reappear intact when you switch back. Nothing was pruned. ## Where the error is produced When you run `docker pull nginx`, the daemon fetches the image's **manifest list** (also called an image index) from the registry. That list is a small JSON document mapping platform descriptors, `os` plus `architecture` plus sometimes `os.version` and `variant`, to concrete image manifests. The daemon then picks the entry matching its own platform. In Windows-container mode that platform is `windows/amd64`. A Linux-only publisher such as the official nginx repository has entries for `linux/amd64`, `linux/arm64`, `linux/arm/v7` and friends, and none for Windows. Selection fails before a single layer is downloaded, and you get: ``` no matching manifest for windows/amd64 in the manifest list entries ``` The variant matters. An older or hand-pushed image may be a single manifest with no list at all. There is no selection step for such an image, so the pull succeeds and the failure moves to `docker run`: ``` docker: image operating system "linux" cannot be used on this platform ``` Both messages say the same thing in different places of the pipeline: this engine cannot run that image's operating system. ## Diagnosing it in ten seconds The useful question is never "is the tag wrong" but "which OS is my engine serving". Two commands answer it: ``` docker info --format '{{.OSType}}' docker version ``` `docker info` prints `windows` or `linux` directly. `docker version` shows a Server block whose `OS/Arch` line reads `windows/amd64` or `linux/amd64`. Note that the Client line may say `windows/amd64` in both modes, because the CLI binary itself is a Windows executable even when it is driving a Linux engine; only the **Server** line tells you the engine's OSType. ## What does not fix it Adding `--platform linux/amd64` to the pull is the most common wrong move. That flag only overrides which entry is selected from the manifest list; it does not give the engine a Linux kernel. In Windows-container mode it converts the pull-time error into the run-time one quoted above. Equally, there is no `--force`, no conversion, and no compatibility shim: Windows containers and Linux containers are two different runtimes that happen to share a CLI, a Dockerfile syntax and a registry protocol. ## The practical consequences The rule bites hardest on mixed stacks. A 23-service local Compose stack of Linux services plus one Windows service cannot be brought up by a single engine at all, no matter how the Compose file is written; the mixed stack needs two engines, and normally two hosts. Teams that hit this usually resolve it by keeping the Windows workload on a dedicated Windows Server host and everything else on Linux, rather than trying to make one developer laptop serve both halves at once. The other consequence is CI. A Windows build agent that has been switched to Windows containers cannot run the Linux tool images the rest of the pipeline uses, so jobs are usually labelled or pinned by OSType rather than mixed on one agent. The failure is loud and early, which is a mercy: the manifest-selection error costs you seconds, whereas a silent partial pull would cost you a debugging session. ## Summary `no matching manifest for windows/amd64` means the engine asked for a Windows image and the repository does not publish one. Confirm the mode with `docker info --format '{{.OSType}}'`, then either switch the engine back to Linux containers or use an image that genuinely ships a Windows entry. The engine will never run both operating systems side by side.

  • After switching modes, docker images no longer lists images you pulled ten minutes ago. What happened to them?
    Nothing. Each mode is a separate engine with its own image store, container list, networks and volumes. The CLI is now talking to the other daemon, so it reports that daemon's contents. Switch back and the earlier images and containers are all still there. No prune ran, and no disk space was reclaimed by the switch.
  • Does adding --platform linux/amd64 make the pull succeed in Windows-container mode?
    It changes which error you get, not whether it works. The flag only selects an entry from the manifest list; the engine still has no Linux kernel to run it on, so the failure moves from the pull to the run and reads `image operating system "linux" cannot be used on this platform`. Selecting an image is not the same as being able to execute it.
  • How would you run one Windows service alongside twenty Linux services locally?
    Not on one engine. You need two engines and normally two hosts: the Windows service on a Windows host serving Windows containers, the rest on a Linux engine, with the two talking over the network. Trying to express both halves in a single Compose file against a single engine fails at image selection for whichever half does not match the engine's OSType.

The registry is a shelf of the same book in several languages; the engine only reads one of them, and asking for a language the publisher never printed gets you an empty shelf, not a translation.

saying these in an interview costs you the question

  • Assumes the image tag is misspelled or deleted
  • Thinks Docker translates Linux images to run on Windows
  • Believes one engine can serve both OS types at once
  • Blames registry downtime or pull rate limits
  • Thinks --platform linux/amd64 makes the image runnable
  • Says switching modes deleted the previous images

context