{"record":{"id":"86257c3ac958ed6a","repo":"docker/cli","slug":"the-plugin-must-be-disabled-before-upgrading","errorCode":null,"errorMessage":"the plugin must be disabled before upgrading","messagePattern":"the plugin must be disabled before upgrading","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/plugin/upgrade.go","lineNumber":51,"sourceCode":"\t}\n\n\tflags := cmd.Flags()\n\tflags.BoolVar(&options.grantPerms, \"grant-all-permissions\", false, \"Grant all permissions necessary to run the plugin\")\n\t// TODO(thaJeztah): DEPRECATED: remove in v29.1 or v30\n\tflags.Bool(\"disable-content-trust\", true, \"Skip image verification (deprecated)\")\n\t_ = flags.MarkDeprecated(\"disable-content-trust\", \"support for docker content trust was removed\")\n\tflags.BoolVar(&options.skipRemoteCheck, \"skip-remote-check\", false, \"Do not check if specified remote plugin matches existing plugin image\")\n\treturn cmd\n}\n\nfunc runUpgrade(ctx context.Context, dockerCLI command.Cli, opts pluginOptions) error {\n\tres, err := dockerCLI.Client().PluginInspect(ctx, opts.localName, client.PluginInspectOptions{})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error reading plugin data: %w\", err)\n\t}\n\n\tif res.Plugin.Enabled {\n\t\treturn errors.New(\"the plugin must be disabled before upgrading\")\n\t}\n\n\topts.localName = res.Plugin.Name\n\tif opts.remote == \"\" {\n\t\topts.remote = res.Plugin.PluginReference\n\t}\n\tremote, err := reference.ParseNormalizedNamed(opts.remote)\n\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","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/plugin/upgrade.go#L33-L69","documentation":"Thrown by runUpgrade after PluginInspect when res.Plugin.Enabled is true. Docker does not allow upgrading a plugin that is currently enabled/running because the upgrade process replaces the plugin rootfs and configuration in place.","triggerScenarios":"Running 'docker plugin upgrade' on a plugin whose enabled state is true (lines 50-52 of upgrade.go).","commonSituations":"Forgetting to disable a plugin before upgrading; plugins that auto-enable on install; scripting an upgrade without the disable step.","solutions":["Disable the plugin first: 'docker plugin disable <name>'.","Then run 'docker plugin upgrade <name>'.","Re-enable after upgrade: 'docker plugin enable <name>'."],"exampleFix":"# before\ndocker plugin upgrade myplugin\n# after\ndocker plugin disable myplugin && docker plugin upgrade myplugin && docker plugin enable myplugin","handlingStrategy":"validation","validationCode":"// Inspect and ensure the plugin is disabled before upgrading\nres, err := apiClient.PluginInspect(ctx, name, client.PluginInspectOptions{})\nif err != nil { return err }\nif res.Plugin.Enabled {\n    if err := apiClient.PluginDisable(ctx, name, client.PluginDisableOptions{}); err != nil { return err }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always disable a plugin before upgrading it.","In automation, disable -> upgrade -> enable as an explicit sequence.","Check the Enabled field via PluginInspect before attempting upgrade."],"tags":["plugin","docker","go","cli","upgrade"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}