goharbor/harbor · error · lib/errors.Error
BAD_REQUEST
BAD_REQUEST
Error message
unsupported content type: %s
What it means
While abstracting v1alpha1 annotations, Harbor pulls the layer annotated as the artifact icon, reads up to 1MB, sniffs the content type with http.DetectContentType, and accepts only GIF, PNG, or JPEG. Any other sniffed type — most commonly SVG (image/svg+xml), WEBP, BMP, ICO, or plain text — returns a BadRequest 'unsupported content type' error.
Source
Thrown at src/controller/artifact/annotation/v1alpha1.go:108
_, icon, err := reg.PullBlob(artifact.RepositoryName, iconDigest)
if err != nil {
return err
}
defer icon.Close()
// check the size of the size <= 1MB
data, err := io.ReadAll(io.LimitReader(icon, 1<<20))
if err != nil {
if err == io.EOF {
return errors.New(nil).WithCode(errors.BadRequestCode).WithMessage("the maximum size of the icon is 1MB")
}
return err
}
// check the content type
contentType := http.DetectContentType(data)
switch contentType {
case GIF, PNG, JPEG:
default:
return errors.New(nil).WithCode(errors.BadRequestCode).WithMessagef("unsupported content type: %s", contentType)
}
artifact.Icon = iconDigest
return nil
}
View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Convert the icon to PNG, GIF, or JPEG (e.g. rsvg-convert -w 256 -h 256 icon.svg -o icon.png) and re-push
- Keep the icon at or below 1MB or you will hit the separate size error
- Verify locally what Harbor will sniff: go's DetectContentType on the first 512 bytes, or file --mime-type icon.png
- Confirm the icon annotation actually points at the icon layer, not another layer of the artifact
Example fix
# before file icon.svg # icon.svg: SVG Scalable Vector Graphics image -> rejected # after rsvg-convert -w 256 -h 256 icon.svg -o icon.png file icon.png # icon.png: PNG image data -> accepted (also keep <= 1MB)
Defensive patterns
Strategy: validation
Validate before calling
// producer-side pre-check mirroring Harbor's sniff
func iconAcceptable(data []byte) bool {
if len(data) > 1<<20 {
return false // separate 1MB limit
}
switch http.DetectContentType(data) {
case "image/gif", "image/png", "image/jpeg":
return true
}
return false
} Prevention
- Use PNG icons produced by rsvg-convert or ImageMagick, not SVG or WEBP
- Keep icons under 1MB
- Point the icon annotation at the layer that actually contains the image bytes
When it happens
Trigger: Pushing an artifact whose layer carries the v1alpha1 icon annotation but whose bytes are SVG/WEBP/BMP/text; or the annotation pointing at the wrong layer so a non-image blob gets sniffed.
Common situations: Toolchains that annotate SVG icons exported from Figma/design tools, icon converters emitting webp, misannotated layers referencing another blob.
Related errors
- purge upload age should set with with nh, n is the number of
- REQUEST_ENTITY_TOO_LARGE
- NOT_FOUND
- VIOLATE_FOREIGN_KEY_CONSTRAINT
- BAD_REQUEST
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/cbc6e7770509ca83.
Report an issue: GitHub.