{"record":{"id":"96af2bc6895c01f1","repo":"docker/cli","slug":"plugin-upgrade-has-been-cancelled","errorCode":null,"errorMessage":"plugin upgrade has been cancelled","messagePattern":"plugin upgrade has been cancelled","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cli/command/plugin/upgrade.go","lineNumber":77,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"error parsing remote upgrade image reference: %w\", err)\n\t}\n\tremote = reference.TagNameOnly(remote)\n\n\told, err := reference.ParseNormalizedNamed(res.Plugin.PluginReference)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error parsing current image reference: %w\", err)\n\t}\n\told = reference.TagNameOnly(old)\n\n\t_, _ = fmt.Fprintf(dockerCLI.Out(), \"Upgrading plugin %s from %s to %s\\n\", res.Plugin.Name, reference.FamiliarString(old), reference.FamiliarString(remote))\n\tif !opts.skipRemoteCheck && remote.String() != old.String() {\n\t\tr, err := prompt.Confirm(ctx, dockerCLI.In(), dockerCLI.Out(), \"Plugin images do not match, are you sure?\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif !r {\n\t\t\treturn cancelledErr{errors.New(\"plugin upgrade has been cancelled\")}\n\t\t}\n\t}\n\n\toptions, err := buildPullConfig(dockerCLI, opts)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tresponseBody, err := dockerCLI.Client().PluginUpgrade(ctx, opts.localName, client.PluginUpgradeOptions(options))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() {\n\t\t_ = responseBody.Close()\n\t}()\n\tif err := jsonstream.Display(ctx, responseBody, dockerCLI.Out()); err != nil {\n\t\treturn err\n\t}","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/plugin/upgrade.go#L59-L95","documentation":"Returned as a cancelledErr (implementing the Cancelled() marker) from runUpgrade when the remote plugin image differs from the currently installed one and the user declines the 'Plugin images do not match, are you sure?' confirmation prompt. This is an intentional cancellation, not a failure.","triggerScenarios":"Running 'docker plugin upgrade foo newimage:tag' where newimage differs from the current reference, then answering 'n' at the confirmation prompt (lines 71-78 of upgrade.go).","commonSituations":"Operator aborting an upgrade after noticing the image mismatch; scripts prompting interactively; fat-fingering 'n'.","solutions":["If you intended to upgrade, answer 'y' or pass --skip-remote-check to bypass the mismatch prompt.","Treat the cancellation exit code as expected in automation.","Verify the target image reference matches your intent before re-running."],"exampleFix":"# before\ndocker plugin upgrade foo other/image:tag   # then type n\n# after\ndocker plugin upgrade --skip-remote-check foo other/image:tag","handlingStrategy":"try-catch","validationCode":"// Bypass the mismatch prompt when you are sure of the target image\n// by passing --skip-remote-check","typeGuard":null,"tryCatchPattern":"// Treat cancellation as non-fatal in automation\nerr := runUpgrade(ctx, cli, opts)\nif err != nil {\n    var c cancelledErr\n    if errors.As(err, &c) { return nil }\n    return err\n}","preventionTips":["Use --skip-remote-check to avoid the mismatch confirmation when intended.","Detect the Cancelled() marker to distinguish aborts from failures.","Verify the target image reference matches intent before upgrading."],"tags":["plugin","upgrade","docker","go","cli","cancellation"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}