docker/compose · error

unsupported external secret %s

Error message

unsupported external secret %s

What it means

Secrets counterpart of the external-config check: when a service mounts a secret declared 'external: true', compose v2 cannot resolve it (no Swarm secret store lookup) and fails with the secret's resolved name. It needs the secret defined in the project via file or environment.

Source

Thrown at pkg/compose/create.go:1219

	}
	return values, nil
}

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

	secretsDir := "/run/secrets/"
	for _, secret := range s.Secrets {
		target := secret.Target
		if secret.Target == "" {
			target = secretsDir + secret.Source
		} else if !isAbsTarget(secret.Target) {
			target = secretsDir + secret.Target
		}

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

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

		if definedSecret.Environment != "" {
			continue
		}

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

		if _, err := os.Stat(definedSecret.File); os.IsNotExist(err) {

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Drop 'external: true' and provide the secret with file: or environment:
  2. If the secret lives outside the project, copy/bind-mount it as a file and reference that path
  3. Use 'docker stack deploy' if Swarm-managed secrets are required

Example fix

# before
secrets:
  db_password:
    external: true
# after
secrets:
  db_password:
    file: ./secrets/db_password.txt
Defensive patterns

Strategy: validation

Validate before calling

for name, sec := range project.Secrets {
    if sec.External {
        return fmt.Errorf("secret %s is external; provide file: or environment:", name)
    }
}

Try / catch

if err != compose.Up(...); err != nil && strings.Contains(err.Error(), "unsupported external secret") { /* inline the secret as a file and retry */ }

Prevention

When it happens

Trigger: Top-level secrets: entry with external: true (or {external: true, name: X}) referenced from a service's secrets: list during container creation.

Common situations: Swarm stack files reused with compose; secrets created with 'docker secret create' expected to be picked up; multi-environment YAML sharing.

Related errors


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