{"record":{"id":"8fa6d3830ccbce3c","repo":"goharbor/harbor","slug":"bad-request-8fa6d3","errorCode":"BAD_REQUEST","errorMessage":"addition %s isn't supported for %s(manifest version 1)","messagePattern":"addition (.+?) isn't supported for (.+?)\\(manifest version 1\\)","errorType":"validation","errorClass":"lib/errors.Error","httpStatus":400,"severity":"error","filePath":"src/controller/artifact/processor/image/manifest_v1.go","lineNumber":54,"sourceCode":"\n// manifestV1Processor processes image with docker v1 manifest\ntype manifestV1Processor struct {\n}\n\nfunc (m *manifestV1Processor) AbstractMetadata(_ context.Context, artifact *artifact.Artifact, manifest []byte) error {\n\tmani := &schema1.Manifest{}\n\tif err := json.Unmarshal(manifest, mani); err != nil {\n\t\treturn err\n\t}\n\tif artifact.ExtraAttrs == nil {\n\t\tartifact.ExtraAttrs = map[string]any{}\n\t}\n\tartifact.ExtraAttrs[\"architecture\"] = mani.Architecture\n\treturn nil\n}\n\nfunc (m *manifestV1Processor) AbstractAddition(_ context.Context, _ *artifact.Artifact, addition string) (*processor.Addition, error) {\n\treturn nil, errors.New(nil).WithCode(errors.BadRequestCode).\n\t\tWithMessagef(\"addition %s isn't supported for %s(manifest version 1)\", addition, ArtifactTypeImage)\n}\n\nfunc (m *manifestV1Processor) GetArtifactType(_ context.Context, _ *artifact.Artifact) string {\n\treturn ArtifactTypeImage\n}\n\nfunc (m *manifestV1Processor) ListAdditionTypes(_ context.Context, _ *artifact.Artifact) []string {\n\treturn nil\n}\n","sourceCodeStart":36,"sourceCodeEnd":65,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/controller/artifact/processor/image/manifest_v1.go#L36-L65","documentation":"Docker schema 1 (manifest version 1) images support no additions: manifestV1Processor.AbstractAddition rejects every request with BadRequest, with '(manifest version 1)' appended to distinguish it from v2. ListAdditionTypes returns nil for these artifacts.","triggerScenarios":"GET .../artifacts/{ref}/additions/{any} on a schema1 image (media type application/vnd.docker.distribution.manifest.v1+json or its signed variant).","commonSituations":"Ancient images migrated from old registries, Docker pre-1.10 era pushes, mirrors still serving v1 manifests.","solutions":["Do not request additions for schema1 artifacts","Rebuild or re-push the image with a modern builder so it lands as schema2/OCI, then delete the v1 copy","Disable schema1 support in the Harbor registry config to prevent new v1 pushes"],"exampleFix":"# before: legacy v1 image, all additions rejected\n# after: regenerate with a modern builder (produces schema2/OCI manifest) and re-push\ndocker build -t harbor.example.com/proj/app:2.0 . && docker push harbor.example.com/proj/app:2.0","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isSchema1(artifactMediaType string) bool {\n    return artifactMediaType == \"application/vnd.docker.distribution.manifest.v1+json\" ||\n        artifactMediaType == \"application/vnd.docker.distribution.manifest.v1+prettyjws\"\n}\n\n// gate: if isSchema1(art.ManifestMediaType) { skip additions entirely }","tryCatchPattern":"if _, err := m.AbstractAddition(ctx, art, addition); err != nil {\n    if errors.IsErr(err, errors.BadRequestCode) && strings.Contains(err.Error(), \"manifest version 1\") {\n        // schema1 artifact: no additions exist; repush as schema2/OCI to get build_history\n    }\n}","preventionTips":["Rebuild legacy images with a modern builder so they land as schema2/OCI","Disable schema1 manifest pushes in the registry config","Never assume build_history exists on pre-OCI images"],"tags":["go","harbor","image","schema1","additions","legacy"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}