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

  1. Create it first: docker network create mynet (or the shared network e.g. for traefik/proxy)
  2. Fix the name in the compose file to match the existing network
  3. If compose should manage it, remove 'external: true'
  4. 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

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


AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15). Data as JSON: /api/errors/cb8b63bac5de91cd. Report an issue: GitHub.