goharbor/harbor · error · lib/errors.Error

BAD_REQUEST

BAD_REQUEST

Error message

addition %s isn't supported for %s(manifest version 1)

What it means

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.

Source

Thrown at src/controller/artifact/processor/image/manifest_v1.go:54

// manifestV1Processor processes image with docker v1 manifest
type manifestV1Processor struct {
}

func (m *manifestV1Processor) AbstractMetadata(_ context.Context, artifact *artifact.Artifact, manifest []byte) error {
	mani := &schema1.Manifest{}
	if err := json.Unmarshal(manifest, mani); err != nil {
		return err
	}
	if artifact.ExtraAttrs == nil {
		artifact.ExtraAttrs = map[string]any{}
	}
	artifact.ExtraAttrs["architecture"] = mani.Architecture
	return nil
}

func (m *manifestV1Processor) AbstractAddition(_ context.Context, _ *artifact.Artifact, addition string) (*processor.Addition, error) {
	return nil, errors.New(nil).WithCode(errors.BadRequestCode).
		WithMessagef("addition %s isn't supported for %s(manifest version 1)", addition, ArtifactTypeImage)
}

func (m *manifestV1Processor) GetArtifactType(_ context.Context, _ *artifact.Artifact) string {
	return ArtifactTypeImage
}

func (m *manifestV1Processor) ListAdditionTypes(_ context.Context, _ *artifact.Artifact) []string {
	return nil
}

View on GitHub (pinned to 7b2fd08cc5)

Solutions

  1. Do not request additions for schema1 artifacts
  2. Rebuild or re-push the image with a modern builder so it lands as schema2/OCI, then delete the v1 copy
  3. Disable schema1 support in the Harbor registry config to prevent new v1 pushes

Example fix

# before: legacy v1 image, all additions rejected
# after: regenerate with a modern builder (produces schema2/OCI manifest) and re-push
docker build -t harbor.example.com/proj/app:2.0 . && docker push harbor.example.com/proj/app:2.0
Defensive patterns

Strategy: type-guard

Type guard

func isSchema1(artifactMediaType string) bool {
    return artifactMediaType == "application/vnd.docker.distribution.manifest.v1+json" ||
        artifactMediaType == "application/vnd.docker.distribution.manifest.v1+prettyjws"
}

// gate: if isSchema1(art.ManifestMediaType) { skip additions entirely }

Try / catch

if _, err := m.AbstractAddition(ctx, art, addition); err != nil {
    if errors.IsErr(err, errors.BadRequestCode) && strings.Contains(err.Error(), "manifest version 1") {
        // schema1 artifact: no additions exist; repush as schema2/OCI to get build_history
    }
}

Prevention

When it happens

Trigger: GET .../artifacts/{ref}/additions/{any} on a schema1 image (media type application/vnd.docker.distribution.manifest.v1+json or its signed variant).

Common situations: Ancient images migrated from old registries, Docker pre-1.10 era pushes, mirrors still serving v1 manifests.

Related errors


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