docker/compose · error
network %s declared as external, but could not be found
Error message
network %s declared as external, but could not be found
What it means
A network is marked 'external: true' in the compose file, but NetworkList with an exact name filter finds zero matches and the engine is not in Swarm mode, so compose cannot attach to it. On Swarm-enabled hosts compose defers the check because overlay networks may not be registered on every node.
Source
Thrown at pkg/compose/create.go:1493
return net.Name != n.Name && net.ID != n.Name
})
switch len(networks) {
case 1:
return networks[0].ID, nil
case 0:
enabled, err := s.isSwarmEnabled(ctx)
if err != nil {
return "", err
}
if enabled {
// Swarm nodes do not register overlay networks that were
// created on a different node unless they're in use.
// So we can't preemptively check network exists, but
// networkAttach will later fail anyway if network actually doesn't exist
return "swarm", nil
}
return "", fmt.Errorf("network %s declared as external, but could not be found", n.Name)
default:
return "", fmt.Errorf("multiple networks with name %q were found. Use network ID as `name` to avoid ambiguity", n.Name)
}
}
func (s *composeService) createVolume(ctx context.Context, volume types.VolumeConfig) error {
eventName := fmt.Sprintf("Volume %s", volume.Name)
s.events.On(creatingEvent(eventName))
hash, err := VolumeHash(volume)
if err != nil {
return err
}
volume.CustomLabels = volume.CustomLabels.Add(api.ConfigHashLabel, hash)
_, err = s.apiClient().VolumeCreate(ctx, client.VolumeCreateOptions{
Labels: mergeLabels(volume.Labels, volume.CustomLabels),
Name: volume.Name,
Driver: volume.Driver,
DriverOpts: volume.DriverOpts,View on GitHub (pinned to ddc4b044b6)
Solutions
- Create it first: docker network create mynet (or the shared network e.g. for traefik/proxy)
- Fix the name in the compose file to match the existing network
- If compose should manage it, remove 'external: true'
- Verify you are on the right docker context: docker context show && docker network ls
Example fix
# before
networks:
proxy:
external: true
# after (let compose own it)
networks:
proxy: {} Defensive patterns
Strategy: validation
Validate before calling
// exact-name existence check before up
res, err := cli.NetworkList(ctx, client.NetworkListOptions{
Filters: client.Filters{"name": {n.Name}},
})
if err != nil { return err }
if len(res.Items) == 0 { return fmt.Errorf("create network %s first", n.Name) } Try / catch
if err := compose.Up(...); err != nil && strings.Contains(err.Error(), "declared as external, but could not be found") {
_ = cli.NetworkCreate(ctx, n.Name, client.NetworkCreateOptions{CheckDuplicate: true})
err = compose.Up(...)
} Prevention
- Create shared networks in a bootstrap step before compose up
- Automate network creation in CI scripts
- Double-check docker context before depending on host-local networks
When it happens
Trigger: networks: {mynet: {external: true}} where no Docker network with exactly that name exists; typical during 'up' when resolving external networks via resolveExternalNetwork.
Common situations: Forgot to create the network beforehand (docker network create mynet); typo in the network name; running on a different engine/context than where the network lives; network removed by prune.
Related errors
- multiple networks with name %q were found. Use network ID as
- cannot publish compose file with local includes
- use_api_socket can't be used with a Windows Docker Engine
- healthcheck.start_interval requires healthcheck.start_period
- Docker Compose does not support configs.*.driver
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/cb8b63bac5de91cd.
Report an issue: GitHub.