Repository navigation
[Bug]: ate-setup doesn't check for the docker buildx plugin and fails mid-install with "unknown flag: --platform" #2873
Description
What happened?
On a host where Docker is installed but the buildx CLI plugin is not (for example Docker CE from
Docker's apt repo without the separate docker-buildx-plugin package), a build-from-source
ate-setup deploy ate-system fails only when it reaches the envoy-dataplane image, with:
unknown flag: --platform
Error: while building the envoy-dataplane image: exit status 125
Two problems:
- The error is misleading. Without the plugin, the docker CLI does not recognize
buildxand
reports the next flag as unknown, so the message points at--platformrather than the
missing plugin.ate-setuponly addswhile building the envoy-dataplane image: exit status 125
(dockerfile.go#L109). - The failure happens after the installer has already written to the cluster. On latest main
(Kind), by the time it failed the cluster had: theate-systemand
podcertificate-controller-systemnamespaces, the CRDs, 4 Secrets (actor-id-jwt-pool,
actor-id-ca-pool,actor-id-ca-certs,ate-api-server-secret-envvars), 5 ConfigMaps, a
runningpodcertificate-controllerDeployment, 4 ClusterTrustBundles, a SandboxConfig, and a
running bundledpostgresStatefulSet. On v0.5.0 (GKE) it failed even later, after the
ate-system bundle (35 objects) was applied, because v0.5.0 builds envoy only while rendering
atenet-egress.
The only Docker preflight today is the Kind-only docker info check added in #2403
(kindcheck.go#L33); nothing checks for buildx. The docs don't list it either: README.md#L113 lists
Go, kubectl and docker, and commands.md#L84-L85 says a source build "needs docker as well as
ko".
Code:
- docker buildx build command:
args := []string{"buildx", "build", "--platform=" + platforms, "--push"} - error wrap:
return "", fmt.Errorf("while building the %s image: %w", imageName, err) - envoy built while rendering the system manifests (dataplane
envoy, the default):imageReference, err := e.dockerfileImage(ctx, envoyDataplaneImage, envoyDataplaneDockefile) - that render runs at deploy.go#L130, after the cluster writes at L82–L126:
substrate/cmd/ate-setup/internal/steps/deploy.go
Lines 82 to 130 in fd17a2f
if err := e.EnsureAteSystemNamespace(ctx); err != nil { return err } // DeployCRDs, not EnsureCRDs: an existence check would skip upgrades, // stranding stale CRD schemas and RBAC (role.yaml has no other apply // path). if err := e.DeployCRDs(ctx); err != nil { return err } if err := e.EnsureAPIServerPrerequisites(ctx); err != nil { return err } // The podcertificate controller goes first so it starts signing and // publishing trust bundles immediately. if err := e.DeployPodCertificateController(ctx); err != nil { return err } if err := e.SetupCSI(ctx, opts.SetupCSI); err != nil { return err } if err := e.DeploySandboxConfig(ctx); err != nil { return err } // Ahead of the bundle below, for the same reason as the namespace: every // workload pulls this ConfigMap in via envFrom, and a container whose // envFrom target is missing will not start. if err := e.applyOtelConfig(ctx); err != nil { return err } // Resolved before the bundle apply: adopting a Cloud SQL instance reads // the ConfigMap that EnsureAPIServerPrerequisites has already rewritten, // and the answer decides both the apply and the rollout wait below. The // bundled database is rendered at its final size before the apply, so the // rollout wait covers the one pod that will actually serve. postgres, err := e.planPostgres(ctx) if err != nil { return err } if err := e.deployPostgres(ctx, postgres); err != nil { return err } manifests, err := e.renderSystemManifests(ctx)
Expected Behavior
When a build from source will need docker buildx, ate-setup checks for it before making any
change to the cluster, and fails with an actionable message, e.g. "docker buildx plugin not found
(docker buildx version failed); install it (https://docs.docker.com/go/buildx/), or use
--image-repo for a pre-built install". A pre-built install (--image-repo) builds nothing and
should not require buildx (env.go#L170-L178 already skips the build in that case).
The prerequisite is also documented next to Go/kubectl/docker.
Steps to Reproduce
Any host without the buildx plugin reproduces it. On a host that has it, hiding the user plugin
directory simulates a missing plugin (only works if buildx is not also installed in the system
plugin directories such as /usr/libexec/docker/cli-plugins):
hack/create-kind-cluster.shmkdir -p /tmp/nobuildx && echo '{}' > /tmp/nobuildx/config.jsonDOCKER_CONFIG=/tmp/nobuildx hack/install-ate-kind.sh --deploy-ate-system --credential-provider='{"name":"k8s.io"}'- The install fails at the envoy-dataplane build with
unknown flag: --platform/exit status 125. kubectl get ns,crd; kubectl -n ate-system get sts,secret,cmshows the partial install.
Minimal, no cluster:
DOCKER_CONFIG=/tmp/nobuildx docker buildx build --platform=linux/amd64 --push -t example.invalid/x:1 .
printsunknown flag: --platform, exit 125DOCKER_CONFIG=/tmp/nobuildx docker buildx version
printsdocker: unknown command: docker buildx, exit 1 (a cheap preflight probe)
Sandbox Runtime
Both / Runtime Agnostic
Agent Substrate Version / Commit SHA
main @ fd17a2f (also reproduced on v0.5.0)
Kubernetes Version & Environment
kind (kindest/node v1.37.0) on latest main; also GKE 1.36.4 on v0.5.0
Host OS & Architecture
Linux 7.1 (x86_64), Docker CE 29.7.1 (docker-ce / docker-ce-cli from Docker's apt repo)
Relevant Logs and Diagnostic Output
[step]: deploy_ate_system
[step]: deploy_crds
[step]: images: built from source with ko
[step]: ensure_apiserver_prerequisites
[step]: create_jwt_authority_pool_secret
[step]: create_actor_id_ca_pool_secret
[step]: create_actor_id_ca_certs_secret
[step]: create_api_server_env_vars
[step]: create_api_config
[step]: create_api_authentication_config
[step]: create_podcertificate_controller_cas
(rollout status deployment/podcertificate-controller took 2.006s)
(wait for clustertrustbundles took 10.016s)
[step]: setup_csi
[step]: deploy_sandboxconfig
[step]: ensure_crds
[step]: setup_bundled_postgres
(rollout status statefulset/postgres took 20.005s)
unknown flag: --platform
Usage: docker [OPTIONS] COMMAND [ARG...]
Run 'docker --help' for more information
Error: while building the envoy-dataplane image: exit status 125
the settings this run used were written to ~/.cache/ate-setup/failed/kind-kind-<timestamp>.yamlAdditional Context
Possible fix (happy to send a PR):
- In
DeployAteSystem(before the first cluster write at deploy.go#L82),DeployAtenet, and
PublishReleaseImages(publish.go#L85), rundocker buildx versionwhen
!Cfg.Images.IsPrebuilt()and fail with the message above. Tests in the style of Report missing Kind and control-plane prerequisites before deployment #2403. - Name the buildx plugin in README.md#L113 and cmd/ate-setup/commands.md#L84-L85.
Related: #2403 (Kind/Docker preflight), #1962 (different buildx issue, closed), #2730 (published
images would avoid source builds).
Confirmation
- I have searched existing issues and verified that this is not a duplicate.
- I have verified that this issue occurs on the latest commit on
main.
Activity
ktsoator commentedon Oct 20, 2026
Hi :)
Is anyone working on this? If not, I'd be happy to pick it up.
SamPriyadarshi commentedon Oct 20, 2026
Hi ktsoator (@ktsoator) , I have a fix for it. Just waiting on maintainers to give a go ahead.
ktsoator commentedon Oct 20, 2026
Got it, thanks for letting me know! :)