{"record":{"id":"6c0fa91aadd1571f","repo":"docker/cli","slug":"network-q-is-declared-as-external-but-could-not","errorCode":null,"errorMessage":"network %q is declared as external, but could not be found. You need to create a swarm-scoped network before the stack is deployed","messagePattern":"network %q is declared as external, but could not be found\\. You need to create a swarm-scoped network before the stack is deployed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/stack/deploy_composefile.go","lineNumber":100,"sourceCode":"\t\t}\n\t\tfor nw := range serviceConfig.Networks {\n\t\t\tserviceNetworks[nw] = struct{}{}\n\t\t}\n\t}\n\treturn serviceNetworks\n}\n\nfunc validateExternalNetworks(ctx context.Context, apiClient client.NetworkAPIClient, externalNetworks []string) error {\n\tfor _, networkName := range externalNetworks {\n\t\tif !container.NetworkMode(networkName).IsUserDefined() {\n\t\t\t// Networks that are not user defined always exist on all nodes as\n\t\t\t// local-scoped networks, so there's no need to inspect them.\n\t\t\tcontinue\n\t\t}\n\t\tres, err := apiClient.NetworkInspect(ctx, networkName, client.NetworkInspectOptions{})\n\t\tswitch {\n\t\tcase errdefs.IsNotFound(err):\n\t\t\treturn fmt.Errorf(\"network %q is declared as external, but could not be found. You need to create a swarm-scoped network before the stack is deployed\", networkName)\n\t\tcase err != nil:\n\t\t\treturn err\n\t\tcase res.Network.Scope != \"swarm\":\n\t\t\treturn fmt.Errorf(\"network %q is declared as external, but it is not in the right scope: %q instead of \\\"swarm\\\"\", networkName, res.Network.Scope)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc createSecrets(ctx context.Context, dockerCLI command.Cli, secrets []swarm.SecretSpec) error {\n\tapiClient := dockerCLI.Client()\n\n\tfor _, secretSpec := range secrets {\n\t\tres, err := apiClient.SecretInspect(ctx, secretSpec.Name, client.SecretInspectOptions{})\n\t\tswitch {\n\t\tcase err == nil:\n\t\t\t// secret already exists, then we update that\n\t\t\t_, err := apiClient.SecretUpdate(ctx, res.Secret.ID, client.SecretUpdateOptions{","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/stack/deploy_composefile.go#L82-L118","documentation":"Raised by validateExternalNetworks when a Compose network declared as external (external: true) does not exist on the Swarm. External networks must be pre-created by the operator because stack deploy will not create them; the check fails fast with a NotFound (errdefs.IsNotFound) from NetworkInspect.","triggerScenarios":"Deploying a stack whose compose file declares `networks: { foo: { external: true } }` while no network named 'foo' exists. The loop in deploy_composefile.go:90 calls NetworkInspect for each external network and, on NotFound, returns this error before any service is deployed.","commonSituations":"Forgetting to `docker network create -d overlay foo` before deploying; using a different name in compose than the actual network; deploying against a fresh Swarm that hasn't had shared networks provisioned; environment drift between staging and prod Swarms.","solutions":["Pre-create the network as swarm-scoped overlay: `docker network create -d overlay <name>`.","Make the compose entry match the real network name (external networks use their actual name, no stack prefix).","If the network should be managed by the stack, remove `external: true` so stack deploy creates it.","Document required pre-existing networks in your deploy runbook/automation."],"exampleFix":"# before (compose.yml)\nnetworks:\n  shared:\n    external: true\n# after\ndocker network create -d overlay shared\ndocker stack deploy -c compose.yml mystack","handlingStrategy":"validation","validationCode":"// Pre-flight: ensure each external network exists and is swarm-scoped before deploy\nfunc ensureExternalNetworks(ctx context.Context, c client.NetworkAPIClient, names []string) error {\n    for _, name := range names {\n        res, err := c.NetworkInspect(ctx, name, client.NetworkInspectOptions{})\n        if errdefs.IsNotFound(err) {\n            return fmt.Errorf(\"external network %q missing; create it with: docker network create -d overlay %s\", name, name)\n        } else if err != nil {\n            return err\n        } else if res.Network.Scope != \"swarm\" {\n            return fmt.Errorf(\"external network %q is %q-scoped, needs swarm\", name, res.Network.Scope)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := stackDeploy(ctx, cli, opts, cfg); err != nil {\n    if strings.Contains(err.Error(), \"declared as external, but could not be found\") {\n        // prompt operator to pre-create, then retry\n    }\n    return err\n}","preventionTips":["Run a pre-flight check that inspects every external network before deploy.","Provision shared networks as part of infra bootstrap, not the stack.","Keep external network names in a single documented inventory."],"tags":["docker","stack","network","external","swarm","not-found"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}