docker/cli · error

error parsing remote upgrade image reference

Error message

error parsing remote upgrade image reference: %w

What it means

Returned by runUpgrade (plugin/upgrade.go:60) wrapping the error from reference.ParseNormalizedNamed on the remote upgrade target. The remote ref (explicit arg or the plugin's stored PluginReference) must be a valid distribution reference; if parsing fails the upgrade aborts before contacting the registry.

Solutions

  1. Supply a valid name[:tag][@digest] reference for the remote.
  2. Omit the remote argument to reuse the plugin's original PluginReference.
  3. Validate the string with reference.ParseNormalizedNamed before invoking.

Example fix

// before
docker plugin upgrade myplugin 'bad name!'
// after
docker plugin upgrade myplugin myrepo/myplugin:latest
Defensive patterns

Strategy: validation

Validate before calling

// Validate the remote reference before upgrading.
func validateRemoteRef(remote string) error {
    if _, err := reference.ParseNormalizedNamed(remote); err != nil {
        return fmt.Errorf("invalid remote upgrade reference %q: %w", remote, err)
    }
    return nil
}

Type guard

// isValidRemoteRef reports whether remote parses as a normalized named reference.
func isValidRemoteRef(remote string) bool {
    _, err := reference.ParseNormalizedNamed(remote)
    return err == nil
}

Prevention

When it happens

Trigger: Running `docker plugin upgrade PLUGIN <remote>` where <remote> is not a valid image reference: contains illegal characters, uppercase in the wrong place, spaces, or invalid syntax. Example: `docker plugin upgrade myplugin 'bad name!'`.

Common situations: Typo in the tag, missing registry prefix, illegal characters in the name, or passing a local path instead of a reference.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/433847cb71125d69. Report an issue: GitHub.

Appendix: source

Thrown at cli/command/plugin/upgrade.go:60

}

func runUpgrade(ctx context.Context, dockerCLI command.Cli, opts pluginOptions) error {
	res, err := dockerCLI.Client().PluginInspect(ctx, opts.localName, client.PluginInspectOptions{})
	if err != nil {
		return fmt.Errorf("error reading plugin data: %w", err)
	}

	if res.Plugin.Enabled {
		return errors.New("the plugin must be disabled before upgrading")
	}

	opts.localName = res.Plugin.Name
	if opts.remote == "" {
		opts.remote = res.Plugin.PluginReference
	}
	remote, err := reference.ParseNormalizedNamed(opts.remote)
	if err != nil {
		return fmt.Errorf("error parsing remote upgrade image reference: %w", err)
	}
	remote = reference.TagNameOnly(remote)

	old, err := reference.ParseNormalizedNamed(res.Plugin.PluginReference)
	if err != nil {
		return fmt.Errorf("error parsing current image reference: %w", err)
	}
	old = reference.TagNameOnly(old)

	_, _ = fmt.Fprintf(dockerCLI.Out(), "Upgrading plugin %s from %s to %s\n", res.Plugin.Name, reference.FamiliarString(old), reference.FamiliarString(remote))
	if !opts.skipRemoteCheck && remote.String() != old.String() {
		r, err := prompt.Confirm(ctx, dockerCLI.In(), dockerCLI.Out(), "Plugin images do not match, are you sure?")
		if err != nil {
			return err
		}
		if !r {
			return cancelledErr{errors.New("plugin upgrade has been cancelled")}
		}

View on GitHub (pinned to 4f84911bfe)