{"id":"08e2cc79a96600e1","repo":"docker/cli","slug":"cannot-attach-to-a-stopped-container-start-it-fir","errorCode":null,"errorMessage":"cannot attach to a stopped container, start it first","messagePattern":"cannot attach to a stopped container, start it first","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/container/attach.go","lineNumber":31,"sourceCode":"\t\"github.com/moby/sys/signal\"\n\t\"github.com/sirupsen/logrus\"\n\t\"github.com/spf13/cobra\"\n)\n\n// AttachOptions group options for `attach` command\ntype AttachOptions struct {\n\tNoStdin    bool\n\tProxy      bool\n\tDetachKeys string\n}\n\nfunc inspectContainerAndCheckState(ctx context.Context, apiClient client.APIClient, args string) (*container.InspectResponse, error) {\n\tc, err := apiClient.ContainerInspect(ctx, args, client.ContainerInspectOptions{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !c.Container.State.Running {\n\t\treturn nil, errors.New(\"cannot attach to a stopped container, start it first\")\n\t}\n\tif c.Container.State.Paused {\n\t\treturn nil, errors.New(\"cannot attach to a paused container, unpause it first\")\n\t}\n\tif c.Container.State.Restarting {\n\t\treturn nil, errors.New(\"cannot attach to a restarting container, wait until it is running\")\n\t}\n\n\treturn &c.Container, nil\n}\n\n// newAttachCommand creates a new cobra.Command for `docker attach`\nfunc newAttachCommand(dockerCLI command.Cli) *cobra.Command {\n\tvar opts AttachOptions\n\n\tcmd := &cobra.Command{\n\t\tUse:   \"attach [OPTIONS] CONTAINER\",\n\t\tShort: \"Attach local standard input, output, and error streams to a running container\",","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/docker/cli/blob/e9452d6e785f6e365712b9d71bd7517591773c86/cli/command/container/attach.go#L13-L49","documentation":"Raised by inspectContainerAndCheckState in cli/command/container/attach.go: before attaching streams, `docker attach` inspects the container and requires State.Running to be true. Attaching to a stopped container is meaningless — there is no live process whose stdio could be streamed — so the CLI rejects it client-side instead of letting the attach hang or fail obscurely.","triggerScenarios":"`docker attach <container>` where ContainerInspect reports State.Running == false — the container exited, was stopped with `docker stop`, or was created (`docker create`) but never started.","commonSituations":"Attaching to a container whose main process crashed immediately (bad entrypoint, missing binary) so it looks 'there' in `docker ps -a` but isn't running; race conditions in scripts that attach right after a container exits; confusing `docker create` with `docker run` and attaching before any start.","solutions":["Start the container first: `docker start <container>`, then attach — or do both at once with `docker start -ai <container>`.","Check why it stopped before restarting: `docker ps -a` for the exit code and `docker logs <container>` for output.","If you wanted a shell in a running container rather than its main process, use `docker exec -it <container> sh` (exec also requires it to be running)."],"exampleFix":"# before\ndocker attach myapp   # Error: cannot attach to a stopped container\n# after\ndocker start -ai myapp","handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":["docker-cli","container-lifecycle","attach"],"analyzedSha":"e9452d6e785f6e365712b9d71bd7517591773c86","analyzedAt":"2026-08-01T07:09:22.474Z","schemaVersion":2}