goharbor/harbor · error · Exception

purge upload interval should set with with nh, n is the numb

Error message

purge upload interval should set with with nh, n is the number of hour and n should not beless than 2

What it means

The field-level check in SBOM manager Create: a non-nil report must carry a non-zero ArtifactID plus non-empty RegistrationUUID, MimeType and MediaType. Missing any one returns 'malformed sbom report object' before the UUID is generated and the row inserted.

Source

Thrown at make/photon/prepare/models.py:226

    def validate(self):
        if not self.enabled:
            return
        # age should end with h
        if not isinstance(self.age, str) or not self.age.endswith('h'):
            raise Exception('purge upload age should set with with nh, n is the number of hour')
        # interval should larger than 2h
        age = self.age[:-1]
        if not age.isnumeric() or int(age) < 2:
            raise Exception('purge upload age should set with with nh, n is the number of hour and n should not be less than 2')

        # interval should end with h
        if not isinstance(self.interval, str) or not self.interval.endswith('h'):
            raise Exception('purge upload interval should set with with nh, n is the number of hour')
        # interval should larger than 2h
        interval = self.interval[:-1]
        if not interval.isnumeric() or int(interval) < 2:
            raise Exception('purge upload interval should set with with nh, n is the number of hour and n should not beless than 2')
        return


class Cache:
    def __init__(self, config: dict):
        if not config:
            self.enabled = False
        self.enabled = config.get('enabled')
        self.expire_hours = config.get('expire_hours')

    def validate(self):
        if not self.enabled:
            return

        if not self.expire_hours or self.expire_hours <= 0:
            raise Exception('cache expire hours should be positive number')
        return

View on GitHub (pinned to 7b2fd08cc5)

Solutions

  1. Resolve the artifact ID before building the report and fail clearly if the artifact is not found
  2. Fill registration_uuid from the scanner registration and mime/media types from the SBOM content
  3. Validate the fields where they are produced, not only inside the manager

Example fix

// before
r := &model.Report{
    ArtifactID: artID, // may be 0
    MimeType:  mime,
}
id, err := mgr.Create(ctx, r)

// after
if artID == 0 || regUUID == "" || mime == "" || mediaType == "" {
    return "", fmt.Errorf("incomplete sbom report: artifact=%d reg=%q mime=%q media=%q", artID, regUUID, mime, mediaType)
}
r := &model.Report{ArtifactID: artID, RegistrationUUID: regUUID, MimeType: mime, MediaType: mediaType}
id, err := mgr.Create(ctx, r)
Defensive patterns

Strategy: validation

Validate before calling

if r == nil || r.ArtifactID == 0 || r.RegistrationUUID == "" || r.MimeType == "" || r.MediaType == "" {
    return fmt.Errorf("incomplete sbom report: artifact=%d reg=%q mime=%q media=%q",
        r.GetArtifactID(), r.RegistrationUUID, r.MimeType, r.MediaType)
}
return mgr.Create(ctx, r)

Try / catch

if _, err := mgr.Create(ctx, r); err != nil {
    if strings.Contains(err.Error(), "malformed sbom report object") {
        return errors.New("sbom report needs artifact id, registration uuid, mime and media type")
    }
    return err
}

Prevention

When it happens

Trigger: Creating a model.Report whose artifact_id is 0 because the artifact lookup failed silently, or whose registration uuid, mime type or media type strings were never filled.

Common situations: SBOM ingest code resolving artifact IDs from events that lack them; forgetting MediaType when porting code from the vulnerability report manager (which does not require it); registration UUID not threaded from the scanner registration.

Related errors


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