{"record":{"id":"2fff2b6855f820e2","repo":"argoproj/argo-workflows","slug":"plugin-s-context-cancelled-while-waiting-for-sock","errorCode":null,"errorMessage":"plugin %s context cancelled while waiting for socket at %q: %w","messagePattern":"plugin (.+?) context cancelled while waiting for socket at %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"workflow/artifacts/plugin/plugin.go","lineNumber":68,"sourceCode":"\t\tif !os.IsNotExist(statErr) {\n\t\t\t// If error is not due to missing file, fail immediately\n\t\t\treturn nil, fmt.Errorf(\"plugin %s cannot stat unix socket at %q: %w\", pluginName, socketPath, statErr)\n\t\t}\n\n\t\t// Socket doesn't exist yet, log at debug level and retry\n\t\tlogger.WithFields(logging.Fields{\n\t\t\t\"pluginName\": pluginName,\n\t\t\t\"socketPath\": socketPath,\n\t\t\t\"retry\":      retry,\n\t\t\t\"maxRetries\": maxRetries,\n\t\t}).Debug(ctx, \"plugin socket not found, retrying in 1s\")\n\n\t\t// Use context-aware sleep\n\t\tselect {\n\t\tcase <-time.After(time.Second):\n\t\t\t// Continue to next iteration\n\t\tcase <-ctx.Done():\n\t\t\treturn nil, fmt.Errorf(\"plugin %s context cancelled while waiting for socket at %q: %w\", pluginName, socketPath, ctx.Err())\n\t\t}\n\t}\n\n\t// If socket still doesn't exist after all retries, fail with error\n\tif !socketExists {\n\t\treturn nil, fmt.Errorf(\"plugin %s expected unix socket at %q but it does not exist after waiting for %d seconds\", pluginName, socketPath, maxRetries)\n\t}\n\n\tif (info.Mode() & os.ModeSocket) == 0 {\n\t\tlogger.WithFields(logging.Fields{\n\t\t\t\"pluginName\": pluginName,\n\t\t\t\"socketPath\": socketPath,\n\t\t\t\"mode\":       info.Mode(),\n\t\t}).Warn(ctx, \"plugin socket file exists but is not a unix socket\")\n\t}\n\tlogger.WithFields(logging.Fields{\n\t\t\"pluginName\": pluginName,\n\t\t\"socketPath\": socketPath,","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/artifacts/plugin/plugin.go#L50-L86","documentation":"While NewDriver polls for the plugin's unix socket (once per second, up to 120s), it selects on the caller's context. If the context is cancelled or its deadline expires during the wait, the driver aborts and wraps ctx.Err() so callers can distinguish cancellation from a genuine plugin-startup failure.","triggerScenarios":"NewDriver called with a ctx whose deadline (e.g. connectionTimeout or a step timeout) expires before the plugin creates its socket, or the caller/parent workflow cancels the context while the socket is still absent.","commonSituations":"Plugin container is slow to start (image pull, slow init) and the caller used a short connectionTimeoutSeconds; node/workflow cancellation racing plugin startup; test harness cancelling ctx early.","solutions":["Increase the artifact plugin's connectionTimeoutSeconds in the workflow/plugin configuration","Investigate why the plugin is slow to create its socket (image pull latency, init failures in plugin logs)","Retry the artifact operation with a fresh, non-cancelled context","Check whether the workflow/node was deliberately cancelled and treat this as expected cleanup, not a bug"],"exampleFix":"// before\nplugin:\n  name: my-plugin\n  connectionTimeoutSeconds: 10\n// after\nplugin:\n  name: my-plugin\n  connectionTimeoutSeconds: 120","handlingStrategy":"retry","validationCode":"select {\ncase <-ctx.Done():\n    return ctx.Err() // bail out before calling NewDriver if already cancelled\ndefault:\n}\nif connectionTimeout < 120*time.Second {\n    // plugin may take up to 120s to bind; give the ctx at least that long\n}","typeGuard":null,"tryCatchPattern":"drv, err := plugin.NewDriver(ctx, name, path, timeout)\nif err != nil {\n    var ce context.CancelCauseError\n    if errors.As(err, &ce) || errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {\n        // treat as cancellation: check whether the workflow was cancelled before retrying\n    }\n    return err\n}","preventionTips":["Set connectionTimeoutSeconds well above expected plugin startup time","Pre-pull plugin images so startup is fast","Distinguish deliberate workflow cancellation from plugin slowness before retrying"],"tags":["context-cancelled","timeout","unix-socket","plugin-driver"],"backgroundTag":"context-cancelled","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}