docker/compose · error

the classic builder doesn't support secrets, set DOCKER_BUIL

Error message

the classic builder doesn't support secrets, set DOCKER_BUILDKIT=1 to use BuildKit

What it means

Returned by doBuildClassic when a service's build section declares secrets (`build.secrets`) and the classic builder path was selected. The classic builder cannot mount secret files into the build container; only BuildKit's `RUN --mount=type=secret` supports this. Compose fails fast instead of silently building without the secrets.

Source

Thrown at pkg/compose/build_classic.go:146

		dockerfileCtx io.ReadCloser
		contextDir    string
		relDockerfile string
	)

	if len(service.Build.Platforms) > 1 {
		return "", fmt.Errorf("the classic builder doesn't support multi-arch build, set DOCKER_BUILDKIT=1 to use BuildKit")
	}
	if service.Build.Privileged {
		return "", fmt.Errorf("the classic builder doesn't support privileged mode, set DOCKER_BUILDKIT=1 to use BuildKit")
	}
	if len(service.Build.AdditionalContexts) > 0 {
		return "", fmt.Errorf("the classic builder doesn't support additional contexts, set DOCKER_BUILDKIT=1 to use BuildKit")
	}
	if len(service.Build.SSH) > 0 {
		return "", fmt.Errorf("the classic builder doesn't support SSH keys, set DOCKER_BUILDKIT=1 to use BuildKit")
	}
	if len(service.Build.Secrets) > 0 {
		return "", fmt.Errorf("the classic builder doesn't support secrets, set DOCKER_BUILDKIT=1 to use BuildKit")
	}

	if service.Build.Labels == nil {
		service.Build.Labels = make(map[string]string)
	}
	service.Build.Labels[api.ImageBuilderLabel] = "classic"

	dockerfileName := dockerFilePath(service.Build.Context, service.Build.Dockerfile)
	specifiedContext := service.Build.Context
	progBuff := s.stdout()
	buildBuff := s.stdout()

	contextType, err := build.DetectContextType(specifiedContext)
	if err != nil {
		return "", err
	}

	switch contextType {

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Enable BuildKit: export DOCKER_BUILDKIT=1 (and unset any DOCKER_BUILDKIT=0), then rebuild
  2. Upgrade Docker CLI/daemon to >= 18.09 (modern installs default to BuildKit, no env var needed)
  3. If stuck on classic, drop `build.secrets` and pass sensitive data another way (e.g. pre-fetch into the context and rely on .dockerignore, or bake at image publish time)

Example fix

# before
# DOCKER_BUILDKIT=0 docker compose build  -> error

# after
export DOCKER_BUILDKIT=1
docker compose build
Defensive patterns

Strategy: validation

Validate before calling

if len(svc.Build.Secrets) > 0 {
    if bk, _ := dockerCli.BuildKitEnabled(); !bk {
        return fmt.Errorf("service %s requires BuildKit for build.secrets", svc.Name)
    }
}

Prevention

When it happens

Trigger: `docker compose build` with `build.secrets` entries (e.g. `secrets: - my_token`) while DOCKER_BUILDKIT=0 or an environment where BuildKitEnabled() returns false routes the build to doBuildClassic.

Common situations: Teams migrating builds to use secret mounts while CI still exports DOCKER_BUILDKIT=0; air-gapped environments with legacy daemons where BuildKit cannot be enabled; copy-pasted Compose files using secrets with an old Docker install.

Related errors


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