{"record":{"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/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/container/attach.go#L13-L49","documentation":"inspectContainerAndCheckState (cli/command/container/attach.go:25), used by `docker attach`, inspects the target container and at line 30-31 returns errors.New(\"cannot attach to a stopped container, start it first\") when c.Container.State.Running is false. Attaching requires a live process to stream I/O from, so a stopped/exited container is rejected client-side before the attach API call.","triggerScenarios":"Running `docker attach <id>` against a container whose state is 'exited', 'created', 'dead', or otherwise not Running; attaching to a container that crashed/exited between your check and the call.","commonSituations":"Container exited immediately (bad entrypoint, missing args); short-lived foreground process already finished; attaching to a container started with -d that has since stopped; race where the container exits right before attach.","solutions":["Start the container first: `docker start <id>` then `docker attach <id>`.","Use `docker ps -a` to confirm the container's STATUS; if Exited, inspect logs (`docker logs <id>`) to see why it stopped.","For one-shot processes, reconsider attach — use `docker run` (foreground) or `docker logs` instead.","If it exits immediately, fix the entrypoint/command and recreate the container."],"exampleFix":"# before (container is stopped)\ndocker attach web\n# after\ndocker start web && docker attach web","handlingStrategy":"validation","validationCode":"// Check container state before attempting attach:\nc, err := cli.Client().ContainerInspect(ctx, id, client.ContainerInspectOptions{})\nif err != nil { return err }\nif !c.State.Running {\n    return fmt.Errorf(\"container %s is not running; start it first\", id)\n}","typeGuard":null,"tryCatchPattern":"if _, err := inspectContainerAndCheckState(ctx, cli.Client(), id); err != nil {\n    if strings.Contains(err.Error(), \"cannot attach to a stopped container\") {\n        // start the container, then retry attach\n    }\n    return err\n}","preventionTips":["Verify STATUS with `docker ps` before attach.","For one-shot workloads, prefer `docker run` over attach.","Check `docker logs` if the container exited unexpectedly."],"tags":["container","attach","lifecycle","validation"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}