{"record":{"id":"6c5d3bd6303e82f9","repo":"docker/compose","slug":"the-classic-builder-doesn-t-support-ssh-keys-set","errorCode":null,"errorMessage":"the classic builder doesn't support SSH keys, set DOCKER_BUILDKIT=1 to use BuildKit","messagePattern":"the classic builder doesn't support SSH keys, set DOCKER_BUILDKIT=1 to use BuildKit","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/compose/build_classic.go","lineNumber":143,"sourceCode":"func (s *composeService) doBuildImage(ctx context.Context, project *types.Project, service types.ServiceConfig, options api.BuildOptions) (string, error) {\n\tvar (\n\t\tbuildCtx      io.ReadCloser\n\t\tdockerfileCtx io.ReadCloser\n\t\tcontextDir    string\n\t\trelDockerfile string\n\t)\n\n\tif len(service.Build.Platforms) > 1 {\n\t\treturn \"\", fmt.Errorf(\"the classic builder doesn't support multi-arch build, set DOCKER_BUILDKIT=1 to use BuildKit\")\n\t}\n\tif service.Build.Privileged {\n\t\treturn \"\", fmt.Errorf(\"the classic builder doesn't support privileged mode, set DOCKER_BUILDKIT=1 to use BuildKit\")\n\t}\n\tif len(service.Build.AdditionalContexts) > 0 {\n\t\treturn \"\", fmt.Errorf(\"the classic builder doesn't support additional contexts, set DOCKER_BUILDKIT=1 to use BuildKit\")\n\t}\n\tif len(service.Build.SSH) > 0 {\n\t\treturn \"\", fmt.Errorf(\"the classic builder doesn't support SSH keys, set DOCKER_BUILDKIT=1 to use BuildKit\")\n\t}\n\tif len(service.Build.Secrets) > 0 {\n\t\treturn \"\", fmt.Errorf(\"the classic builder doesn't support secrets, set DOCKER_BUILDKIT=1 to use BuildKit\")\n\t}\n\n\tif service.Build.Labels == nil {\n\t\tservice.Build.Labels = make(map[string]string)\n\t}\n\tservice.Build.Labels[api.ImageBuilderLabel] = \"classic\"\n\n\tdockerfileName := dockerFilePath(service.Build.Context, service.Build.Dockerfile)\n\tspecifiedContext := service.Build.Context\n\tprogBuff := s.stdout()\n\tbuildBuff := s.stdout()\n\n\tcontextType, err := build.DetectContextType(specifiedContext)\n\tif err != nil {\n\t\treturn \"\", err","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/pkg/compose/build_classic.go#L125-L161","documentation":"Returned by doBuildClassic when a service's build section declares SSH keys (`build.ssh`) but the legacy classic builder is in use. The classic builder has no mechanism to forward SSH agent keys into the build, so Compose aborts before invoking the builder. BuildKit is required because only it implements `#syntax` SSH mount forwarding.","triggerScenarios":"Running `docker compose build` (or `up --build`) on a service with `build.ssh` configured while the code path resolves to doBuildClassic — i.e. DOCKER_BUILDKIT=0 is set, or the docker CLI/daemon is old enough that BuildKit is not the default, and COMPOSE_BAKE/BUILDKIT escalation is disabled.","commonSituations":"CI pipelines pinning DOCKER_BUILDKIT=0 for reproducibility; corporate baselines with old dockerd versions; composing files that added `ssh:` to fetch private repos during RUN git clone; DOCKER_BUILDKIT explicitly disabled to get classic builder logs.","solutions":["Set DOCKER_BUILDKIT=1 in the environment (or remove DOCKER_BUILDKIT=0) and re-run the build","Alternatively set COMPOSE_BAKE=true or ensure the Docker CLI >= 18.09 and daemon >= 18.09 so BuildKit is the default","If the classic builder is mandatory, remove the `ssh:` block from the service's build section and use a non-SSH strategy (e.g. build args with a deploy key, or a multistage fetch outside the build)"],"exampleFix":"# docker-compose.yml (before)\nservices:\n  app:\n    build:\n      context: .\n      ssh:\n        - default  # fails with classic builder\n\n# after: enable BuildKit\n# export DOCKER_BUILDKIT=1\ndocker compose build","handlingStrategy":"validation","validationCode":"// before building, reject classic builder if build.ssh is used\nif len(svc.Build.SSH) > 0 {\n    bk, err := dockerCli.BuildKitEnabled()\n    if err != nil {\n        return err\n    }\n    if !bk {\n        return fmt.Errorf(\"service %s needs DOCKER_BUILDKIT=1 for build.ssh\", svc.Name)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set DOCKER_BUILDKIT=1 globally in CI environments that build Compose projects with ssh/secrets","Lint Compose files: fail CI if build.ssh/build.secrets exist while DOCKER_BUILDKIT is 0"],"tags":["build","buildkit","ssh","classic-builder"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}