goharbor/harbor · error · lib/errors.Error

NOT_FOUND

NOT_FOUND

Error message

repository %s not found

What it means

Returned by repository manager GetByName when the List query on Name returns zero rows. The lookup is exact-match on the repository name, so this NOT_FOUND error means no repository record with exactly that name exists in Harbor's database.

Source

Thrown at src/pkg/repository/manager.go:87

	}
	return repositories, nil
}

func (m *manager) Get(ctx context.Context, id int64) (*model.RepoRecord, error) {
	return m.dao.Get(ctx, id)
}

func (m *manager) GetByName(ctx context.Context, name string) (repository *model.RepoRecord, err error) {
	repositories, err := m.List(ctx, &q.Query{
		Keywords: map[string]any{
			"Name": name,
		},
	})
	if err != nil {
		return nil, err
	}
	if len(repositories) == 0 {
		return nil, errors.New(nil).WithCode(errors.NotFoundCode).
			WithMessagef("repository %s not found", name)
	}
	return repositories[0], nil
}

func (m *manager) Create(ctx context.Context, repository *model.RepoRecord) (int64, error) {
	return m.dao.Create(ctx, repository)
}

func (m *manager) Delete(ctx context.Context, id int64) error {
	return m.dao.Delete(ctx, id)
}
func (m *manager) Update(ctx context.Context, repository *model.RepoRecord, props ...string) error {
	return m.dao.Update(ctx, repository, props...)
}

func (m *manager) AddPullCount(ctx context.Context, id int64, count uint64) error {
	return m.dao.AddPullCount(ctx, id, count)

View on GitHub (pinned to 7b2fd08cc5)

Solutions

  1. Verify the exact name including the project prefix and case, e.g. library/ubuntu not ubuntu
  2. List repositories with a query to confirm the record exists at all
  3. If the image was pushed only to the registry without triggering record creation, trigger the post-push event/scan or use the API that creates the record
  4. If retention deleted it, restore or re-push the image

Example fix

// before
repo, err := repoMgr.GetByName(ctx, "ubuntu")
// err: repository ubuntu not found

// after
repo, err := repoMgr.GetByName(ctx, "library/ubuntu")
if err != nil {
    if errors.IsErr(err, errors.NotFoundCode) {
        // handle absent repository record
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// Normalize and check the name shape before lookup
name = strings.Trim(name, "/")
if !strings.Contains(name, "/") {
    return fmt.Errorf("repository name must include project prefix: %s", name)
}
repo, err := repoMgr.GetByName(ctx, name)

Try / catch

repo, err := repoMgr.GetByName(ctx, name)
if err != nil {
    if errors.IsErr(err, errors.NotFoundCode) {
        // absent record: create placeholder or return 404 to caller
    }
    return err
}

Prevention

When it happens

Trigger: Calling GetByName with a name that has never been created (Harbor auto-creates records on first push, so a never-pushed repo has no record); using the wrong separator or case ( Harbor stores names like project/repo and matching is exact); the repository was deleted by retention or API.

Common situations: Querying metadata for a repo that exists in the registry but has no DB record yet (image pushed via docker but API metadata queried before record creation); retention policy already removed the repo; typos or URL-encoded names ('project%2Frepo' vs 'project/repo'); replication target not yet synced.

Related errors


AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16). Data as JSON: /api/errors/b173d8fa5fe5428c. Report an issue: GitHub.