docker/compose · error

the classic builder doesn't support additional contexts, set

Error message

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

What it means

On the classic build path, doBuildImage rejects any service declaring build.additional_contexts. Additional build contexts (named contexts passed to the Dockerfile via --build-context) are implemented only by BuildKit's builder; the legacy API accepts a single context tarball and cannot attach extra named sources, so compose fails fast with the DOCKER_BUILDKIT=1 hint.

Source

Thrown at pkg/compose/build_classic.go:140

}

//nolint:gocyclo
func (s *composeService) doBuildImage(ctx context.Context, project *types.Project, service types.ServiceConfig, options api.BuildOptions) (string, error) {
	var (
		buildCtx      io.ReadCloser
		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()

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Enable BuildKit (unset DOCKER_BUILDKIT / COMPOSE_BAKE; ensure buildx installed) so additional contexts work
  2. If stuck on the classic builder, inline the extra source into the main build context (COPY from within the context) and remove additional_contexts
  3. Pre-build the dependency image and reference it by tag instead of a named context

Example fix

# before (compose.yaml)
services:
  app:
    build:
      context: .
      additional_contexts:
        deps: ../deps
# + DOCKER_BUILDKIT=0 -> error
# after
$ unset DOCKER_BUILDKIT
$ docker compose build app
Defensive patterns

Strategy: validation

Validate before calling

// Guard before a classic-path build:
for name, svc := range project.Services {
	if svc.Build != nil && len(svc.Build.AdditionalContexts) > 0 && classicBuilder() {
		return fmt.Errorf("service %s requires BuildKit for additional_contexts", name)
	}
}

Prevention

When it happens

Trigger: A compose service uses build.additional_contexts (e.g. mapping 'src' to another service's image or a local path for a COPY --from=src step) while the build is routed to the classic builder via DOCKER_BUILDKIT=0, COMPOSE_BAKE=false, or a missing buildx plugin.

Common situations: Multi-service build sharing sources through named contexts; COPY --from=other-service patterns; hosts where BuildKit was disabled for firewall reasons but the compose file assumes modern features.

Related errors


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