golang-migrate/migrate · warning

error closing Docker client: %w

Error message

error closing Docker client: %w

What it means

In dktesting, after provisioning/tearing down a container the deferred Docker client close error is captured into retErr and wrapped as 'error closing Docker client: %w', so a cleanup-time client failure surfaces instead of being silently dropped.

Source

Thrown at dktesting/dktesting.go:28

	"github.com/moby/moby/client"
)

// ContainerSpec holds Docker testing setup specifications
type ContainerSpec struct {
	ImageName string
	Options   dktest.Options
}

// Cleanup cleanups the ContainerSpec after a test run by removing the ContainerSpec's image
func (s *ContainerSpec) Cleanup() (retErr error) {
	// copied from dktest.RunContext()
	dc, err := client.New(client.FromEnv, client.WithAPIVersion("1.41"))
	if err != nil {
		return err
	}
	defer func() {
		if err := dc.Close(); err != nil && retErr == nil {
			retErr = fmt.Errorf("error closing Docker client: %w", err)
		}
	}()
	cleanupTimeout := s.Options.CleanupTimeout
	if cleanupTimeout <= 0 {
		cleanupTimeout = dktest.DefaultCleanupTimeout
	}
	ctx, timeoutCancelFunc := context.WithTimeout(context.Background(), cleanupTimeout)
	defer timeoutCancelFunc()
	if _, err := dc.ImageRemove(ctx, s.ImageName, client.ImageRemoveOptions{Force: true, PruneChildren: true}); err != nil {
		if errdefs.IsNotFound(err) {
			return nil
		}
		return err
	}
	return nil
}

// ParallelTest runs Docker tests in parallel

View on GitHub (pinned to 01a9643f14)

Solutions

  1. Check DOCKER_HOST and Docker daemon health; restart the daemon or fix the socket path
  2. Remove or correct DOCKER_API_VERSION env overrides so client.FromEnv and WithAPIVersion("1.41") negotiate properly
  3. Re-run the tests — a close-time error is usually transient and does not indicate a test failure
  4. Report/inspect the wrapped %w cause for the underlying net/url error

Example fix

// before
DOCKER_API_VERSION=nonsense go test ./...
// after
unset DOCKER_API_VERSION
go test ./...
Defensive patterns

Strategy: try-catch

Validate before calling

if os.Getenv("DOCKER_HOST") != "" {
    if _, err := net.Dial("unix", strings.TrimPrefix(os.Getenv("DOCKER_HOST"), "unix://")); err != nil {
        return fmt.Errorf("docker daemon unreachable: %w", err)
    }
}

Try / catch

err := dktesting.Parallel(...)
var derr *dktesting.Error
if errors.As(err, &derr) && strings.Contains(derr.Error(), "error closing Docker client") {
    log.Printf("docker client cleanup issue (usually transient): %v", err)
}

Prevention

When it happens

Trigger: A test container spec (parallel tests via Parallel) finishing while the Docker client (created via client.New with FromEnv) fails to close — e.g. broken DOCKER_HOST connection or API version negotiation issues.

Common situations: CI environments with flaky Docker daemons or remote DOCKER_HOST sockets; mismatched DOCKER_API_VERSION overrides; tests ignoring that the reported error may mask the test's real return error (retErr is only set if no earlier error).

Related errors


AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02). Data as JSON: /api/errors/b5df21772e3aaae5. Report an issue: GitHub.