docker/compose · error

unsupported external config %s

Error message

unsupported external config %s

What it means

Returned when building container configs for a service that references a config declared with 'external: true'. Docker Compose (the Go v2 implementation) cannot materialize external configs the way Swarm does — it needs the config defined in the project (file, content, or environment) so it can mount it.

Source

Thrown at pkg/compose/create.go:1169

	}
	return m, nil
}

func buildContainerConfigMounts(p types.Project, s types.ServiceConfig) ([]mount.Mount, error) {
	mounts := map[string]mount.Mount{}

	configsBaseDir := "/"
	for _, config := range s.Configs {
		target := config.Target
		if config.Target == "" {
			target = configsBaseDir + config.Source
		} else if !isAbsTarget(config.Target) {
			target = configsBaseDir + config.Target
		}

		definedConfig := p.Configs[config.Source]
		if definedConfig.External {
			return nil, fmt.Errorf("unsupported external config %s", definedConfig.Name)
		}

		if definedConfig.Driver != "" {
			return nil, errors.New("Docker Compose does not support configs.*.driver") //nolint:staticcheck
		}
		if definedConfig.TemplateDriver != "" {
			return nil, errors.New("Docker Compose does not support configs.*.template_driver") //nolint:staticcheck
		}

		if definedConfig.Environment != "" || definedConfig.Content != "" {
			continue
		}

		if config.UID != "" || config.GID != "" || config.Mode != nil {
			logrus.Warn("config `uid`, `gid` and `mode` are not supported, they will be ignored")
		}

		bindMount, err := buildMount(p, types.ServiceVolumeConfig{

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Remove 'external: true' and define the config inline (file:, content:, or environment:)
  2. If the config was created out-of-band, point file: at the same source file instead
  3. For Swarm-only workflows, keep using 'docker stack deploy' rather than compose

Example fix

# before
configs:
  mycert:
    external: true
# after
configs:
  mycert:
    file: ./certs/server.pem
Defensive patterns

Strategy: validation

Validate before calling

// preflight the compose model before Create/Up
for name, cfg := range project.Configs {
    if cfg.External {
        return fmt.Errorf("config %s is external; define it with file/content/environment", name)
    }
}

Try / catch

if err := compose.Up(ctx, ...); err != nil && strings.Contains(err.Error(), "unsupported external config") { /* rewrite config inline and retry */ }

Prevention

When it happens

Trigger: A compose file where the top-level configs: section has an entry with external: true (or external with a name), and a service mounts that config; CreateContainer then hits this branch in the config loop.

Common situations: Porting a docker-stack/swarm YAML to compose v2; leftover external: from a Swarm deployment; configs created out-of-band with 'docker config create' expected to be reused.

Related errors


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