goharbor/harbor · error · NotFoundError
repo %v, tag %v not found
Error message
repo %v, tag %v not found
What it means
Error "repo %v, tag %v not found" thrown in goharbor/harbor.
Source
Thrown at src/controller/proxy/controller.go:196
if a != nil && len(art.Digest) > 0 {
return true, nil, nil
}
remoteRepo := GetRemoteRepo(art)
exist, desc, err := remote.ManifestExist(remoteRepo, getReference(art)) // HEAD
if err != nil {
if errors.IsRateLimitError(err) && a != nil { // if rate limit, use local if it exists, otherwise return error
return true, nil, nil
}
return false, nil, err
}
if !exist || desc == nil {
// if not found in remote and local artifact exists, check if we should serve from local cache
if a != nil && p != nil && p.ProxyCacheLocalOnNotFound() {
log.Infof("Artifact not found in remote registry but exists in local cache, serving from local: %v:%v", art.Repository, art.Tag)
return true, nil, nil
}
return false, nil, errors.NotFoundError(fmt.Errorf("repo %v, tag %v not found", art.Repository, art.Tag))
}
var content []byte
var contentType string
if c.cache == nil {
return a != nil && string(desc.Digest) == a.Digest, nil, nil // digest matches
}
// Pass digest to the cache key, digest is more stable than tag, because tag could be updated
if len(art.Digest) == 0 {
art.Digest = string(desc.Digest)
}
err = c.cache.Fetch(ctx, manifestListKey(art.Repository, art), &content)
if err != nil {
if errors.Is(err, cache.ErrNotFound) {
log.Debugf("Digest is not found in manifest list cache, key=cache:%v", manifestListKey(art.Repository, art))
} else {
log.Errorf("Failed to get manifest list from cache, error: %v", err)
}View on GitHub (pinned to 7b2fd08cc5)
When it happens
Trigger: Thrown at src/controller/proxy/controller.go:196 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/d6c879b28e7c16ee.
Report an issue: GitHub.