goharbor/harbor · error · lib/errors.Error
NOT_FOUND
NOT_FOUND
Error message
The sbom is not found
What it means
The SBOM processor serves Harbor's internal SBOM attachment media type application/vnd.goharbor.harbor.sbom.v1. AbstractAddition pulls the artifact's own manifest and requires exactly one layer; a manifest with zero or multiple layers returns NotFound 'The sbom is not found', signaling that the SBOM attachment is missing or malformed.
Source
Thrown at src/controller/artifact/processor/sbom/sbom.go:68
}
// AbstractAddition returns the addition for SBOM
func (m *Processor) AbstractAddition(_ context.Context, art *artifact.Artifact, _ string) (*processor.Addition, error) {
man, _, err := m.RegCli.PullManifest(art.RepositoryName, art.Digest)
if err != nil {
return nil, errors.Wrap(err, "failed to pull manifest")
}
_, payload, err := man.Payload()
if err != nil {
return nil, errors.Wrap(err, "failed to get payload")
}
manifest := &v1.Manifest{}
if err := json.Unmarshal(payload, manifest); err != nil {
return nil, err
}
// SBOM artifact should only have one layer
if len(manifest.Layers) != 1 {
return nil, errors.New(nil).WithCode(errors.NotFoundCode).WithMessage("The sbom is not found")
}
layerDgst := manifest.Layers[0].Digest.String()
_, blob, err := m.RegCli.PullBlob(art.RepositoryName, layerDgst)
if err != nil {
return nil, errors.Wrap(err, "failed to pull the blob")
}
defer blob.Close()
content, err := io.ReadAll(blob)
if err != nil {
return nil, err
}
return &processor.Addition{
Content: content,
ContentType: processorMediaType,
}, nil
}
// GetArtifactType the artifact type is used to display the artifact type in the UIView on GitHub (pinned to 7b2fd08cc5)
Solutions
- Delete the malformed SBOM attachment artifact and rescan the parent so the attachment is regenerated
- Inspect the attachment manifest via the registry API (GET by digest) and count layers
- If producing attachments yourself, push exactly one layer containing the SBOM content
Example fix
# before: attachment manifest has 0 layers (interrupted push) -> 'The sbom is not found' # after: remove and regenerate curl -X DELETE .../artifacts/sha256:<sbom-attachment-digest> # then rescan the parent artifact so Trivy re-attaches a single-layer SBOM
Defensive patterns
Strategy: try-catch
Try / catch
content, err := sbomProc.AbstractAddition(ctx, art, "sbom")
if err != nil {
if errors.IsErr(err, errors.NotFoundCode) && strings.Contains(err.Error(), "sbom is not found") {
// attachment malformed/missing: delete it and rescan the parent artifact
}
return err
} Prevention
- Rescan the parent artifact to regenerate SBOM attachments after job interruptions
- Verify attachments have exactly one layer before relying on them
- Treat NotFound from the sbom addition as 'regenerate', not 'fatal'
When it happens
Trigger: Requesting the SBOM addition when the referenced attachment artifact's manifest has no layers (manifest-only push) or more than one (assembled incorrectly); interrupted attachment pushes leave empty manifests.
Common situations: Trivy/Harbor SBOM attachments partially pushed after a job interruption, attachments created with the wrong layer layout, hand-pushed SBOM artifacts with extra layers.
Related errors
- purge upload age should set with with nh, n is the number of
- purge upload interval should set with with nh, n is the numb
- purge upload interval should set with with nh, n is the numb
- cache expire hours should be positive number
- invalid quota update provider: {}
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/712d63a6933a39ea.
Report an issue: GitHub.