{"record":{"id":"b5df21772e3aaae5","repo":"golang-migrate/migrate","slug":"error-closing-docker-client-w","errorCode":null,"errorMessage":"error closing Docker client: %w","messagePattern":"error closing Docker client: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"dktesting/dktesting.go","lineNumber":28,"sourceCode":"\t\"github.com/moby/moby/client\"\n)\n\n// ContainerSpec holds Docker testing setup specifications\ntype ContainerSpec struct {\n\tImageName string\n\tOptions   dktest.Options\n}\n\n// Cleanup cleanups the ContainerSpec after a test run by removing the ContainerSpec's image\nfunc (s *ContainerSpec) Cleanup() (retErr error) {\n\t// copied from dktest.RunContext()\n\tdc, err := client.New(client.FromEnv, client.WithAPIVersion(\"1.41\"))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() {\n\t\tif err := dc.Close(); err != nil && retErr == nil {\n\t\t\tretErr = fmt.Errorf(\"error closing Docker client: %w\", err)\n\t\t}\n\t}()\n\tcleanupTimeout := s.Options.CleanupTimeout\n\tif cleanupTimeout <= 0 {\n\t\tcleanupTimeout = dktest.DefaultCleanupTimeout\n\t}\n\tctx, timeoutCancelFunc := context.WithTimeout(context.Background(), cleanupTimeout)\n\tdefer timeoutCancelFunc()\n\tif _, err := dc.ImageRemove(ctx, s.ImageName, client.ImageRemoveOptions{Force: true, PruneChildren: true}); err != nil {\n\t\tif errdefs.IsNotFound(err) {\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// ParallelTest runs Docker tests in parallel","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/dktesting/dktesting.go#L10-L46","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Check DOCKER_HOST and Docker daemon health; restart the daemon or fix the socket path","Remove or correct DOCKER_API_VERSION env overrides so client.FromEnv and WithAPIVersion(\"1.41\") negotiate properly","Re-run the tests — a close-time error is usually transient and does not indicate a test failure","Report/inspect the wrapped %w cause for the underlying net/url error"],"exampleFix":"// before\nDOCKER_API_VERSION=nonsense go test ./...\n// after\nunset DOCKER_API_VERSION\ngo test ./...","handlingStrategy":"try-catch","validationCode":"if os.Getenv(\"DOCKER_HOST\") != \"\" {\n    if _, err := net.Dial(\"unix\", strings.TrimPrefix(os.Getenv(\"DOCKER_HOST\"), \"unix://\")); err != nil {\n        return fmt.Errorf(\"docker daemon unreachable: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"err := dktesting.Parallel(...)\nvar derr *dktesting.Error\nif errors.As(err, &derr) && strings.Contains(derr.Error(), \"error closing Docker client\") {\n    log.Printf(\"docker client cleanup issue (usually transient): %v\", err)\n}","preventionTips":["Ensure DOCKER_HOST points to a reachable daemon socket/URL","Avoid setting DOCKER_API_VERSION to values incompatible with your daemon","Retry flaky container tests before diagnosing a real failure","Check daemon health (docker info) in CI before the test suite"],"tags":["go","docker","testing","cleanup","network"],"backgroundTag":"docker-client-cleanup-failed","analyzedSha":"01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a","analyzedAt":"2026-09-02T19:38:29.671Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}