goharbor/harbor · error · Exception
purge upload age should set with with nh, n is the number of
Error message
purge upload age should set with with nh, n is the number of hour
What it means
The second ScanRequest.Validate check: Artifact must be non-nil with non-empty Digest, Repository and MimeType — these identify the exact manifest the adapter must scan. Missing any one of the four yields 'scan request: invalid artifact'.
Source
Thrown at make/photon/prepare/models.py:214
self.otel.validate()
class PurgeUpload:
def __init__(self, config: dict):
if not config:
self.enabled = False
self.enabled = config.get('enabled')
self.age = config.get('age') or '168h'
self.interval = config.get('interval') or '24h'
self.dryrun = config.get('dryrun') or False
return
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:View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Complete all artifact fields (digest, repository, mime type) before submitting the scan
- Validate at event-ingestion time and requeue artifacts that are incomplete
- Validate fields individually in logs so the exact missing field is visible
Example fix
// before
req := &v1.ScanRequest{
Registry: &v1.Registry{URL: cfg.RegistryURL},
Artifact: &v1.Artifact{Repository: "library/nginx"}, // digest + mime_type missing
}
// after
req := &v1.ScanRequest{
Registry: &v1.Registry{URL: cfg.RegistryURL},
Artifact: &v1.Artifact{
Repository: "library/nginx",
Digest: "sha256:abc...",
MimeType: v1.MimeTypeDockerArtifact,
},
} Defensive patterns
Strategy: validation
Validate before calling
if req.Artifact == nil || req.Artifact.Digest == "" || req.Artifact.Repository == "" || req.Artifact.MimeType == "" {
return fmt.Errorf("scan request missing artifact fields: %+v", req.Artifact)
}
return req.Validate() Try / catch
if err := req.Validate(); err != nil {
if strings.Contains(err.Error(), "invalid artifact") {
return errors.New("artifact digest, repository and mime type are all required")
}
return err
} Prevention
- Only enqueue scans for fully indexed artifacts (digest present)
- Validate artifact payloads at event-ingestion time and requeue incomplete ones
- Log which specific field is empty using a per-field check
When it happens
Trigger: req.Validate() where artifact, digest, repository, or mime_type is empty — e.g. a scan enqueued for an artifact whose manifest digest was not yet populated by replication or event processing.
Common situations: Scans triggered before the artifact is fully replicated or indexed; event handlers forwarding partial artifact payloads; upstream systems changing digest formats or field names.
Related errors
- File {} not exist
- Internal dir for tls {} not exist
- Port number in metrics is not valid
- Jaeger Colector Endpoint or Agent host not set, must set one
- Jaeger Colector Endpoint and Agent host both set, only can s
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/f4d1e662f1892bcc.
Report an issue: GitHub.