goharbor/harbor · error · lib/errors.Error

NotFoundCode

NotFoundCode

Error message

the reference tries to refer a non existing label %d or artifact %d

What it means

Returned when inserting a row into the label-artifact reference table violates a foreign key constraint: the LabelID or ArtifactID in the new Reference does not exist in the database (label or artifact row missing/deleted). Harbor converts the ORM foreign-key error into a 404 NotFoundCode, surfaced by POST /api/v2.0/projects/{project}/repositories/{repo}/artifacts/{reference}/labels.

Source

Thrown at src/pkg/label/dao/dao.go:169

	labels := []*model.Label{}
	if _, err = ormer.Raw(sql, artifactID).QueryRows(&labels); err != nil {
		return nil, err
	}
	return labels, nil
}
func (d *defaultDAO) CreateReference(ctx context.Context, ref *model.Reference) (int64, error) {
	ormer, err := orm.FromContext(ctx)
	if err != nil {
		return 0, err
	}
	id, err := ormer.Insert(ref)
	if err != nil {
		if e := orm.AsConflictError(err, "label %d is already added to the artifact %d",
			ref.LabelID, ref.ArtifactID); e != nil {
			err = e
		} else if e := orm.AsForeignKeyError(err, "the reference tries to refer a non existing label %d or artifact %d",
			ref.LabelID, ref.ArtifactID); e != nil {
			err = errors.New(e).WithCode(errors.NotFoundCode).WithMessage(e.Message)
		}
	}
	return id, err
}

func (d *defaultDAO) DeleteReference(ctx context.Context, id int64) error {
	ormer, err := orm.FromContext(ctx)
	if err != nil {
		return err
	}
	n, err := ormer.Delete(&model.Reference{
		ID: id,
	})
	if err != nil {
		return err
	}
	if n == 0 {
		return errors.NotFoundError(nil).WithMessagef("label reference %d not found", id)

View on GitHub (pinned to 7b2fd08cc5)

Solutions

  1. List the labels actually visible to the artifact's project (GET /api/v2.0/projects/{project_id}/labels and GET /api/v2.0/labels?scope=g) and re-submit with a current ID.
  2. Verify the artifact exists (GET .../artifacts/{reference}) and re-resolve it if a retention/GC job may have deleted it.
  3. If the label was deleted, re-create it and re-attach, or remove that step from your automation.

Example fix

# before
curl -X POST https://harbor/api/v2.0/projects/myproj/repositories/myrepo/artifacts/sha256:abc.../labels -d '{"id": 42}'
# after: re-list labels to get a valid id first
curl https://harbor/api/v2.0/projects/1/labels   # -> pick existing id, e.g. 7
curl -X POST https://harbor/api/v2.0/projects/myproj/repositories/myrepo/artifacts/sha256:abc.../labels -d '{"id": 7}'
Defensive patterns

Strategy: validation

Validate before calling

# REST: resolve label and artifact immediately before attaching
# label must appear in project labels or global labels
labels = GET /api/v2.0/projects/{project_id}/labels + GET /api/v2.0/labels?scope=g
if label_id not in {l.id for l in labels}: fail("label id unknown")
art = GET /api/v2.0/projects/{project}/repositories/{repo}/artifacts/{reference}
if art is 404: fail("artifact gone")

Try / catch

Catch HTTP 404 from POST .../artifacts/{reference}/labels; distinguish FK-not-found (re-list labels and retry once with a fresh ID) from artifact-not-found (skip — artifact deleted by retention/GC).

Prevention

When it happens

Trigger: POST .../artifacts/{reference}/labels with body {"id": <labelID>} where labelID does not exist (deleted or wrong environment's ID), points to a label in another project, or the artifact was concurrently deleted (e.g. garbage collect / retention job) between resolution and insert.

Common situations: Scripts or UI code caching label IDs that were re-created (IDs change across environments/DB rebuilds); attaching a project-scoped label from a different project; races between label deletion and an automated labeling pipeline; copied API examples with hardcoded label IDs.

Related errors


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