docker/cli · error
network is declared as external, but it is not in the right…
Error message
network %q is declared as external, but it is not in the right scope: %q instead of "swarm"
What it means
Raised by validateExternalNetworks when an external network exists but its Scope is not 'swarm' (typically it is 'local', e.g. a bridge or host network). Swarm services can only attach to swarm-scoped (overlay) networks, so a local-scoped network is rejected even though it exists.
Solutions
- Recreate the network as overlay (swarm-scoped): `docker network rm foo && docker network create -d overlay foo`.
- Use a swarm-scoped driver like overlay for any network referenced by Swarm services.
- Verify scope before deploy: `docker network inspect foo --format '{{.Scope}}'` should print 'swarm'.
Example fix
# before docker network create shared # creates local bridge # after docker network create -d overlay shared # creates swarm-scoped overlay
Defensive patterns
Strategy: validation
Validate before calling
// Verify scope of each external network before deploy
for _, name := range externalNetworks {
res, err := c.NetworkInspect(ctx, name, client.NetworkInspectOptions{})
if err != nil { return err }
if res.Network.Scope != "swarm" {
return fmt.Errorf("network %q scope %q; recreate as overlay", name, res.Network.Scope)
}
} Prevention
- Always create shared networks with `-d overlay`.
- Add a CI gate that inspects external network scopes before stack deploy.
- Avoid referencing host/bridge networks from Swarm stacks.
When it happens
Trigger: Declaring `networks: { foo: { external: true } }` where 'foo' was created with a local-scope driver (bridge, host, macvlan in local scope, or default bridge). NetworkInspect succeeds (deploy_composefile.go:97) but res.Network.Scope != "swarm" at line 103.
Common situations: Creating the network with `docker network create foo` (defaults to bridge/local) instead of `-d overlay`; reusing a network built for non-Swarm compose; a network created by `docker-compose` (local) being referenced from a Swarm stack.
Related errors
- network is declared as external, but could not be found…
- failed to create network
- this node is not a swarm manager. Use "docker swarm init"…
- cannot get label com.docker.stack.namespace for service
- failed to remove some resources from stack
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/9f7c1041339ca6fe.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/stack/deploy_composefile.go:104
}
return serviceNetworks
}
func validateExternalNetworks(ctx context.Context, apiClient client.NetworkAPIClient, externalNetworks []string) error {
for _, networkName := range externalNetworks {
if !container.NetworkMode(networkName).IsUserDefined() {
// Networks that are not user defined always exist on all nodes as
// local-scoped networks, so there's no need to inspect them.
continue
}
res, err := apiClient.NetworkInspect(ctx, networkName, client.NetworkInspectOptions{})
switch {
case errdefs.IsNotFound(err):
return 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)
case err != nil:
return err
case res.Network.Scope != "swarm":
return fmt.Errorf("network %q is declared as external, but it is not in the right scope: %q instead of \"swarm\"", networkName, res.Network.Scope)
}
}
return nil
}
func createSecrets(ctx context.Context, dockerCLI command.Cli, secrets []swarm.SecretSpec) error {
apiClient := dockerCLI.Client()
for _, secretSpec := range secrets {
res, err := apiClient.SecretInspect(ctx, secretSpec.Name, client.SecretInspectOptions{})
switch {
case err == nil:
// secret already exists, then we update that
_, err := apiClient.SecretUpdate(ctx, res.Secret.ID, client.SecretUpdateOptions{
Version: res.Secret.Meta.Version,
Spec: secretSpec,
})
if err != nil {View on GitHub (pinned to 4f84911bfe)