{"record":{"id":"480507d1f5560e06","repo":"goharbor/harbor","slug":"the-tag-deletion-isn-t-supported","errorCode":null,"errorMessage":"the tag deletion isn't supported","messagePattern":"the tag deletion isn't supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/pkg/reg/adapter/native/adapter.go","lineNumber":245,"sourceCode":"\treturn filter.DoFilterArtifacts(artifacts, filters)\n}\n\n// PingSimple checks whether the registry is available. It checks the connectivity and certificate (if TLS enabled)\n// only, regardless of 401/403 error.\nfunc (a *Adapter) PingSimple() error {\n\terr := a.Ping()\n\tif err == nil {\n\t\treturn nil\n\t}\n\tif errors.IsErr(err, errors.UnAuthorizedCode) || errors.IsErr(err, errors.ForbiddenCode) {\n\t\treturn nil\n\t}\n\treturn err\n}\n\n// DeleteTag isn't supported for docker registry\nfunc (a *Adapter) DeleteTag(_, _ string) error {\n\treturn errors.New(\"the tag deletion isn't supported\")\n}\n\n// CanBeMount isn't supported for docker registry\nfunc (a *Adapter) CanBeMount(_ string) (mount bool, repository string, err error) {\n\treturn false, \"\", nil\n}\n","sourceCodeStart":227,"sourceCodeEnd":252,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/pkg/reg/adapter/native/adapter.go#L227-L252","documentation":"Returned unconditionally by (*native.Adapter).DeleteTag (src/pkg/reg/adapter/native/adapter.go:245), the adapter for plain Docker Registry v2 endpoints. The Docker Distribution HTTP API has no per-tag delete endpoint (tags are mutable pointers to manifests), so the adapter declares tag deletion unsupported rather than silently doing nothing. Note the sibling DeleteManifest/CanBeMount comments: only manifest/digest operations exist for docker registry.","triggerScenarios":"Invoking adapter.DeleteTag(repository, tag) on the native adapter — directly or via a replication/rule engine that calls tag deletion on a docker-registry-type destination. The method signature accepts any strings but always returns this error.","commonSituations":"Porting logic from Harbor (which supports tag delete via its own artifact model) to a raw docker registry destination; retention/cleanup scripts that try to delete tags on a Distribution registry; version changes where a previously worked-around path now funnels into DeleteTag.","solutions":["Delete by digest instead: resolve the tag to a manifest digest and call DeleteManifest (or the registry DELETE /v2/<name>/manifests/<digest> API).","In Harbor, delete the artifact (which removes all its tags) via the Harbor API rather than the registry adapter.","Check the adapter's Info()/capabilities before attempting tag-level operations and skip unsupported ones.","If per-tag removal is required, run a garbage-collect-enabled retention policy (Harbor retention rules / registry GC) instead of tag deletion."],"exampleFix":"// before\nerr := adapter.DeleteTag(\"myrepo\", \"v1.0\")\n// always: the tag deletion isn't supported\n\n// after\nmanifest, err := adapter.ListTagExist... // resolve digest, e.g. via HEAD /v2/myrepo/manifests/v1.0\ndigest := manifest.Digest\nerr := adapter.DeleteManifest(\"myrepo\", digest.String())","handlingStrategy":"validation","validationCode":"// docker registry (native) has no tag-delete API: gate the call\ninfo, err := adapter.Info()\nif err != nil {\n\treturn err\n}\nif strings.Contains(adapter.Info().Name, \"docker\") {\n\t// skip DeleteTag; use digest-based deletion\n}\n_ = info","typeGuard":"func supportsTagDeletion(a adp.Adapter) bool {\n\t// native.Adapter is the docker registry v2 adapter and rejects DeleteTag\n\t_, isNative := a.(*native.Adapter)\n\treturn !isNative\n}","tryCatchPattern":"if err := adapter.DeleteTag(repo, tag); err != nil {\n\tif strings.Contains(err.Error(), \"tag deletion isn't supported\") {\n\t\t// fall back: resolve tag -> digest, then DeleteManifest(repo, digest)\n\t\treturn adapter.DeleteManifest(repo, digest)\n\t}\n\treturn err\n}","preventionTips":["Model deletions at manifest/digest granularity for docker registry destinations.","Check adapter type/capabilities before tag-level operations.","Use Harbor's artifact deletion API when the destination is Harbor."],"tags":["go","docker-registry","distribution","native-adapter","unsupported-operation","deletion"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}