{"record":{"id":"459f64a85c400318","repo":"docker/cli","slug":"invalid-name-s-459f64","errorCode":null,"errorMessage":"invalid name: %s","messagePattern":"invalid name: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/plugin/push.go","lineNumber":41,"sourceCode":"\t\t},\n\t\tValidArgsFunction:     completeNames(dockerCLI, stateAny),\n\t\tDisableFlagsInUseLine: true,\n\t}\n\n\tflags := cmd.Flags()\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\treturn cmd\n}\n\nfunc runPush(ctx context.Context, dockerCli command.Cli, name string) error {\n\tnamed, err := reference.ParseNormalizedNamed(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif _, ok := named.(reference.Canonical); ok {\n\t\treturn fmt.Errorf(\"invalid name: %s\", name)\n\t}\n\n\tnamed = reference.TagNameOnly(named)\n\tencodedAuth, err := command.RetrieveAuthTokenFromImage(dockerCli.ConfigFile(), named.String())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tresponseBody, err := dockerCli.Client().PluginPush(ctx, reference.FamiliarString(named), client.PluginPushOptions{\n\t\tRegistryAuth: encodedAuth,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() {\n\t\t_ = responseBody.Close()\n\t}()\n\treturn jsonstream.Display(ctx, responseBody, dockerCli.Out())","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/plugin/push.go#L23-L59","documentation":"Returned by runPush (plugin/push.go:41) when the plugin argument parses as a reference.Canonical (digest) reference. Plugin push targets a tagged plugin image in a registry; pushing by digest is not a meaningful operation, so after ParseNormalizedNamed the code checks the Canonical type and rejects it.","triggerScenarios":"Running `docker plugin push myplugin@sha256:abcd1234...`. The push command needs a name:tag, not a digest.","commonSituations":"Copy-pasting a digest from `docker plugin inspect` instead of the tag, or assuming push works like pull-by-digest.","solutions":["Push by name and tag, e.g. `docker plugin push myplugin:latest`.","Tag the plugin first if it only has a digest reference.","Use `docker plugin inspect` to find the tagged PluginReference to push."],"exampleFix":"// before\ndocker plugin push myplugin@sha256:abc123\n// after\ndocker plugin push myplugin:latest","handlingStrategy":"type-guard","validationCode":"// Ensure the push target is a tag, not a digest.\nfunc validatePushTarget(name string) error {\n    ref, err := reference.ParseNormalizedNamed(name)\n    if err != nil { return err }\n    if _, ok := ref.(reference.Canonical); ok {\n        return fmt.Errorf(\"cannot push by digest: %s\", name)\n    }\n    return nil\n}","typeGuard":"// isPushableName reports whether name is a tag (non-canonical) reference.\nfunc isPushableName(name string) bool {\n    ref, err := reference.ParseNormalizedNamed(name)\n    if err != nil { return false }\n    _, ok := ref.(reference.Canonical)\n    return !ok\n}","tryCatchPattern":null,"preventionTips":["Push with name:tag only.","Confirm the plugin has a tag before pushing.","Inspect the plugin to copy the correct tagged reference."],"tags":["plugin","reference","naming","registry","docker-cli"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}