From dfc25f06e16dfcca003ddd30c04ec52c2b969857 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 18 Jun 2026 14:26:27 +0000 Subject: [PATCH] integration: pin docker client to daemon API version dockertest's bundled client builds against API v1.25; Docker Engine 29 rejects it (min 1.40), surfacing as a "broken pipe" that fails every local image build. Pin to the daemon's reported version so builds use a live path. Closes #2937 --- integration/scenario.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/integration/scenario.go b/integration/scenario.go index be19d78b..ab31546d 100644 --- a/integration/scenario.go +++ b/integration/scenario.go @@ -185,6 +185,26 @@ func NewScenario(spec ScenarioSpec) (*Scenario, error) { return nil, fmt.Errorf("connecting to docker: %w", err) } + // dockertest's bundled go-dockerclient stamps image builds with API + // v1.25 (the `ver` tag on BuildImageOptions.Dockerfile) whenever the + // client has no pinned version. Docker Engine 29 raised the minimum API + // version to 1.40 and rejects v1.25 with a 400, which surfaces mid-build + // as a "write: broken pipe". Pin the client to the daemon's reported API + // version so build (and every other) request uses an accepted path. + version, err := pool.Client.Version() + if err != nil { + return nil, fmt.Errorf("querying docker API version: %w", err) + } + + if api := version.Get("ApiVersion"); api != "" { + client, err := docker.NewVersionedClientFromEnv(api) + if err != nil { + return nil, fmt.Errorf("pinning docker client to API version %s: %w", api, err) + } + + pool.Client = client + } + // Opportunity to clean up unreferenced networks. // This might be a no op, but it is worth a try as we sometime // dont clean up nicely after ourselves.