Repository: distribution/distribution
Pull request #3896 (2023-05-03 16:58:06)

Remove blobstore from manifest builder
Rebase from https://github.com/distribution/distribution/pull/2782

> This PR aims to close https://github.com/distribution/distribution/issues/2150 by removing blobstore from schema2 manifest builder.
>
> The builder now take configuration Descriptor as parameter instead of a blobstore and media type.

@milosgajdos friendly ping since you were the one to review the original PR.

DavidSpek: Friendly ping @thaJeztah @squizzi 

Patch:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 4bc90dde..5f9163fb 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -24,7 +24,7 @@ jobs:
       matrix:
         go:
           - 1.18
-          - 1.19.9
+          - 1.19
     steps:
       -
         name: Checkout
diff --git a/.golangci.yml b/.golangci.yml
index 64a494b4..c64ba6e7 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -1,5 +1,7 @@
 linters:
   enable:
+    - structcheck
+    - varcheck
     - staticcheck
     - unconvert
     - gofmt
@@ -12,14 +14,6 @@ linters:
   disable:
     - errcheck
 
-linters-settings:
-  revive:
-    rules:
-      # TODO(thaJeztah): temporarily disabled the "unused-parameter" check.
-      # It produces many warnings, and some of those may need to be looked at.
-      - name: unused-parameter
-        disabled: true
-
 run:
   deadline: 2m
   skip-dirs:
diff --git a/Dockerfile b/Dockerfile
index c6ebb789..d99d8288 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,8 +1,8 @@
 # syntax=docker/dockerfile:1
 
-ARG GO_VERSION=1.19.9
+ARG GO_VERSION=1.18
 ARG ALPINE_VERSION=3.16
-ARG XX_VERSION=1.2.1
+ARG XX_VERSION=1.1.1
 
 FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
 FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS base
@@ -44,8 +44,8 @@ RUN --mount=from=binary,target=/build \
       VERSION=$(cat /tmp/.version) \
       && mkdir -p /out \
       && cp /build/registry /src/README.md /src/LICENSE . \
-      && tar -czvf "/out/registry_${VERSION#v}_${TARGETOS}_${TARGETARCH}${TARGETVARIANT}.tar.gz" * \
-      && sha256sum -z "/out/registry_${VERSION#v}_${TARGETOS}_${TARGETARCH}${TARGETVARIANT}.tar.gz" | awk '{ print $1 }' > "/out/registry_${VERSION#v}_${TARGETOS}_${TARGETARCH}${TARGETVARIANT}.tar.gz.sha256"
+      && tar -czvf "/out/registry_${VERSION#v}_${TARGETOS}_${TARGETARCH}${TARGETVARIANT}.tar.tgz" * \
+      && sha256sum -z "/out/registry_${VERSION#v}_${TARGETOS}_${TARGETARCH}${TARGETVARIANT}.tar.tgz" | awk '{ print $1 }' > "/out/registry_${VERSION#v}_${TARGETOS}_${TARGETARCH}${TARGETVARIANT}.tar.tgz.sha256"
 
 FROM scratch AS artifact
 COPY --from=releaser /out /
diff --git a/configuration/configuration.go b/configuration/configuration.go
index f8a501f7..1f773976 100644
--- a/configuration/configuration.go
+++ b/configuration/configuration.go
@@ -197,8 +197,7 @@ type Configuration struct {
 		} `yaml:"pool,omitempty"`
 	} `yaml:"redis,omitempty"`
 
-	Health  Health  `yaml:"health,omitempty"`
-	Catalog Catalog `yaml:"catalog,omitempty"`
+	Health Health `yaml:"health,omitempty"`
 
 	Proxy Proxy `yaml:"proxy,omitempty"`
 
@@ -261,16 +260,6 @@ type Configuration struct {
 	} `yaml:"policy,omitempty"`
 }
 
-// Catalog is composed of MaxEntries.
-// Catalog endpoint (/v2/_catalog) configuration, it provides the configuration
-// options to control the maximum number of entries returned by the catalog endpoint.
-type Catalog struct {
-	// Max number of entries returned by the catalog endpoint. Requesting n entries
-	// to the catalog endpoint will return at most MaxEntries entries.
-	// An empty or a negative value will set a default of 1000 maximum entries by default.
-	MaxEntries int `yaml:"maxentries,omitempty"`
-}
-
 // LogHook is composed of hook Level and Type.
 // After hooks configuration, it can execute the next handling automatically,
 // when defined levels of log message emitted.
@@ -697,11 +686,6 @@ func Parse(rd io.Reader) (*Configuration, error) {
 					if v0_1.Loglevel != Loglevel("") {
 						v0_1.Loglevel = Loglevel("")
 					}
-
-					if v0_1.Catalog.MaxEntries <= 0 {
-						v0_1.Catalog.MaxEntries = 1000
-					}
-
 					if v0_1.Storage.Type() == "" {
 						return nil, errors.New("no storage configuration provided")
 					}
diff --git a/dockerfiles/git.Dockerfile b/dockerfiles/git.Dockerfile
index debe554e..38effe42 100644
--- a/dockerfiles/git.Dockerfile
+++ b/dockerfiles/git.Dockerfile
@@ -1,6 +1,6 @@
 # syntax=docker/dockerfile:1
 
-ARG GO_VERSION=1.19.9
+ARG GO_VERSION=1.18
 ARG ALPINE_VERSION=3.16
 
 FROM alpine:${ALPINE_VERSION} AS base
diff --git a/dockerfiles/lint.Dockerfile b/dockerfiles/lint.Dockerfile
index a9743c16..113db75a 100644
--- a/dockerfiles/lint.Dockerfile
+++ b/dockerfiles/lint.Dockerfile
@@ -1,8 +1,8 @@
 # syntax=docker/dockerfile:1
 
-ARG GO_VERSION=1.19.9
+ARG GO_VERSION=1.18
 ARG ALPINE_VERSION=3.16
-ARG GOLANGCI_LINT_VERSION=v1.52
+ARG GOLANGCI_LINT_VERSION=v1.45
 
 FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint
 
diff --git a/dockerfiles/vendor.Dockerfile b/dockerfiles/vendor.Dockerfile
index 1ff56095..b56e5ee9 100644
--- a/dockerfiles/vendor.Dockerfile
+++ b/dockerfiles/vendor.Dockerfile
@@ -1,6 +1,6 @@
 # syntax=docker/dockerfile:1
 
-ARG GO_VERSION=1.19.9
+ARG GO_VERSION=1.18
 ARG ALPINE_VERSION=3.16
 ARG MODOUTDATED_VERSION=v0.8.0
 
diff --git a/docs/configuration.md b/docs/configuration.md
index 35c32656..9a53833b 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -159,7 +159,7 @@ storage:
     encrypt: optional enable server-side encryption
     encryptionkeyid: optional KMS key id for encryption
     secure: optional ssl setting
-    chunksize: optional size value
+    chunksize: optional size valye
     rootdirectory: optional root directory
   inmemory:  # This driver takes no parameters
   delete:
@@ -1017,7 +1017,6 @@ accept event notifications.
 | `ignore`  |no| Events with these mediatypes or actions are not published to the endpoint. |
 
 #### `ignore`
-
 | Parameter | Required | Description                                           |
 |-----------|----------|-------------------------------------------------------|
 | `mediatypes`|no| A list of target media types to ignore. Events with these target media types are not published to the endpoint. |
diff --git a/manifest/schema2/builder.go b/manifest/schema2/builder.go
index 52da82e3..585741d0 100644
--- a/manifest/schema2/builder.go
+++ b/manifest/schema2/builder.go
@@ -4,16 +4,12 @@ import (
 	"context"
 
 	"github.com/distribution/distribution/v3"
-	"github.com/opencontainers/go-digest"
 )
 
 // builder is a type for constructing manifests.
 type builder struct {
-	// bs is a BlobService used to publish the configuration blob.
-	bs distribution.BlobService
-
-	// configMediaType is media type used to describe configuration
-	configMediaType string
+	// configDescriptor is used to describe configuration
+	configDescriptor distribution.Descriptor
 
 	// configJSON references
 	configJSON []byte
@@ -26,11 +22,10 @@ type builder struct {
 // NewManifestBuilder is used to build new manifests for the current schema
 // version. It takes a BlobService so it can publish the configuration blob
 // as part of the Build process.
-func NewManifestBuilder(bs distribution.BlobService, configMediaType string, configJSON []byte) distribution.ManifestBuilder {
+func NewManifestBuilder(configDescriptor distribution.Descriptor, configJSON []byte) distribution.ManifestBuilder {
 	mb := &builder{
-		bs:              bs,
-		configMediaType: configMediaType,
-		configJSON:      make([]byte, len(configJSON)),
+		configDescriptor: configDescriptor,
+		configJSON:       make([]byte, len(configJSON)),
 	}
 	copy(mb.configJSON, configJSON)
 
@@ -45,30 +40,7 @@ func (mb *builder) Build(ctx context.Context) (distribution.Manifest, error) {
 	}
 	copy(m.Layers, mb.dependencies)
 
-	configDigest := digest.FromBytes(mb.configJSON)
-
-	var err error
-	m.Config, err = mb.bs.Stat(ctx, configDigest)
-	switch err {
-	case nil:
-		// Override MediaType, since Put always replaces the specified media
-		// type with application/octet-stream in the descriptor it returns.
-		m.Config.MediaType = mb.configMediaType
-		return FromStruct(m)
-	case distribution.ErrBlobUnknown:
-		// nop
-	default:
-		return nil, err
-	}
-
-	// Add config to the blob store
-	m.Config, err = mb.bs.Put(ctx, mb.configMediaType, mb.configJSON)
-	// Override MediaType, since Put always replaces the specified media
-	// type with application/octet-stream in the descriptor it returns.
-	m.Config.MediaType = mb.configMediaType
-	if err != nil {
-		return nil, err
-	}
+	m.Config = mb.configDescriptor
 
 	return FromStruct(m)
 }
diff --git a/registry/api/v2/descriptors.go b/registry/api/v2/descriptors.go
index 8622d0d2..25d91924 100644
--- a/registry/api/v2/descriptors.go
+++ b/registry/api/v2/descriptors.go
@@ -134,19 +134,6 @@ var (
 		},
 	}
 
-	invalidPaginationResponseDescriptor = ResponseDescriptor{
-		Name:        "Invalid pagination number",
-		Description: "The received parameter n was invalid in some way, as described by the error code. The client should resolve the issue and retry the request.",
-		StatusCode:  http.StatusBadRequest,
-		Body: BodyDescriptor{
-			ContentType: "application/json",
-			Format:      errorsBody,
-		},
-		ErrorCodes: []errcode.ErrorCode{
-			ErrorCodePaginationNumberInvalid,
-		},
-	}
-
 	repositoryNotFoundResponseDescriptor = ResponseDescriptor{
 		Name:        "No Such Repository Error",
 		StatusCode:  http.StatusNotFound,
@@ -502,7 +489,18 @@ var routeDescriptors = []RouteDescriptor{
 							},
 						},
 						Failures: []ResponseDescriptor{
-							invalidPaginationResponseDescriptor,
+							{
+								Name:        "Invalid pagination number",
+								Description: "The received parameter n was invalid in some way, as described by the error code. The client should resolve the issue and retry the request.",
+								StatusCode:  http.StatusBadRequest,
+								Body: BodyDescriptor{
+									ContentType: "application/json",
+									Format:      errorsBody,
+								},
+								ErrorCodes: []errcode.ErrorCode{
+									ErrorCodePaginationNumberInvalid,
+								},
+							},
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
@@ -1591,9 +1589,6 @@ var routeDescriptors = []RouteDescriptor{
 								},
 							},
 						},
-						Failures: []ResponseDescriptor{
-							invalidPaginationResponseDescriptor,
-						},
 					},
 				},
 			},
diff --git a/registry/api/v2/errors.go b/registry/api/v2/errors.go
index dcbabfca..23a87f8c 100644
--- a/registry/api/v2/errors.go
+++ b/registry/api/v2/errors.go
@@ -151,8 +151,7 @@ var (
 		Value:   "PAGINATION_NUMBER_INVALID",
 		Message: "invalid number of results requested",
 		Description: `Returned when the "n" parameter (number of results
-		to return) is not an integer, "n" is negative or "n" is bigger than
-		the maximum allowed.`,
+		to return) is not an integer, or "n" is negative.`,
 		HTTPStatusCode: http.StatusBadRequest,
 	})
 )
diff --git a/registry/handlers/catalog.go b/registry/handlers/catalog.go
index 0e633878..b8ed3f45 100644
--- a/registry/handlers/catalog.go
+++ b/registry/handlers/catalog.go
@@ -9,12 +9,11 @@ import (
 	"strconv"
 
 	"github.com/distribution/distribution/v3/registry/api/errcode"
-	v2 "github.com/distribution/distribution/v3/registry/api/v2"
 	"github.com/distribution/distribution/v3/registry/storage/driver"
 	"github.com/gorilla/handlers"
 )
 
-const defaultReturnedEntries = 100
+const maximumReturnedEntries = 100
 
 func catalogDispatcher(ctx *Context, r *http.Request) http.Handler {
 	catalogHandler := &catalogHandler{
@@ -39,58 +38,29 @@ func (ch *catalogHandler) GetCatalog(w http.ResponseWriter, r *http.Request) {
 
 	q := r.URL.Query()
 	lastEntry := q.Get("last")
-
-	entries := defaultReturnedEntries
-	maximumConfiguredEntries := ch.App.Config.Catalog.MaxEntries
-
-	// parse n, if n is negative abort with an error
-	if n := q.Get("n"); n != "" {
-		parsedMax, err := strconv.Atoi(n)
-		if err != nil || parsedMax < 0 {
-			ch.Errors = append(ch.Errors, v2.ErrorCodePaginationNumberInvalid.WithDetail(map[string]string{"n": n}))
-			return
-		}
-
-		// if a client requests more than it's allowed to receive
-		if parsedMax > maximumConfiguredEntries {
-			ch.Errors = append(ch.Errors, v2.ErrorCodePaginationNumberInvalid.WithDetail(map[string]int{"n": parsedMax}))
-			return
-		}
-		entries = parsedMax
+	maxEntries, err := strconv.Atoi(q.Get("n"))
+	if err != nil || maxEntries < 0 {
+		maxEntries = maximumReturnedEntries
 	}
 
-	// then enforce entries to be between 0 & maximumConfiguredEntries
-	// max(0, min(entries, maximumConfiguredEntries))
-	if entries < 0 || entries > maximumConfiguredEntries {
-		entries = maximumConfiguredEntries
-	}
+	repos := make([]string, maxEntries)
 
-	repos := make([]string, entries)
-	filled := 0
+	filled, err := ch.App.registry.Repositories(ch.Context, repos, lastEntry)
+	_, pathNotFound := err.(driver.PathNotFoundError)
 
-	// entries is guaranteed to be >= 0 and < maximumConfiguredEntries
-	if entries == 0 {
+	if err == io.EOF || pathNotFound {
 		moreEntries = false
-	} else {
-		returnedRepositories, err := ch.App.registry.Repositories(ch.Context, repos, lastEntry)
-		if err != nil {
-			_, pathNotFound := err.(driver.PathNotFoundError)
-			if err != io.EOF && !pathNotFound {
-				ch.Errors = append(ch.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
-				return
-			}
-			// err is either io.EOF or not PathNotFoundError
-			moreEntries = false
-		}
-		filled = returnedRepositories
+	} else if err != nil {
+		ch.Errors = append(ch.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
+		return
 	}
 
 	w.Header().Set("Content-Type", "application/json")
 
 	// Add a link header if there are more entries to retrieve
 	if moreEntries {
-		lastEntry = repos[filled-1]
-		urlStr, err := createLinkEntry(r.URL.String(), entries, lastEntry)
+		lastEntry = repos[len(repos)-1]
+		urlStr, err := createLinkEntry(r.URL.String(), maxEntries, lastEntry)
 		if err != nil {
 			ch.Errors = append(ch.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
 			return
diff --git a/registry/handlers/manifests.go b/registry/handlers/manifests.go
index 4434286a..e91fcac0 100644
--- a/registry/handlers/manifests.go
+++ b/registry/handlers/manifests.go
@@ -11,7 +11,7 @@ import (
 	dcontext "github.com/distribution/distribution/v3/context"
 	"github.com/distribution/distribution/v3/manifest/manifestlist"
 	"github.com/distribution/distribution/v3/manifest/ocischema"
-	"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	"github.com/distribution/distribution/v3/manifest/schema1"
 	"github.com/distribution/distribution/v3/manifest/schema2"
 	"github.com/distribution/distribution/v3/reference"
 	"github.com/distribution/distribution/v3/registry/api/errcode"
@@ -260,7 +260,7 @@ func (imh *manifestHandler) convertSchema2Manifest(schema2Manifest *schema2.Dese
 		}
 	}
 
-	builder := schema1.NewConfigManifestBuilder(imh.Repository.Blobs(imh), imh.Context.App.trustKey, ref, configJSON) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	builder := schema1.NewConfigManifestBuilder(imh.Repository.Blobs(imh), imh.Context.App.trustKey, ref, configJSON)
 	for _, d := range schema2Manifest.Layers {
 		if err := builder.AppendReference(d); err != nil {
 			imh.Errors = append(imh.Errors, v2.ErrorCodeManifestInvalid.WithDetail(err))
@@ -272,7 +272,7 @@ func (imh *manifestHandler) convertSchema2Manifest(schema2Manifest *schema2.Dese
 		imh.Errors = append(imh.Errors, v2.ErrorCodeManifestInvalid.WithDetail(err))
 		return nil, err
 	}
-	imh.Digest = digest.FromBytes(manifest.(*schema1.SignedManifest).Canonical) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	imh.Digest = digest.FromBytes(manifest.(*schema1.SignedManifest).Canonical)
 
 	return manifest, nil
 }
@@ -421,7 +421,7 @@ func (imh *manifestHandler) applyResourcePolicy(manifest distribution.Manifest)
 
 	var class string
 	switch m := manifest.(type) {
-	case *schema1.SignedManifest: //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	case *schema1.SignedManifest:
 		class = imageClass
 	case *schema2.DeserializedManifest:
 		switch m.Config.MediaType {
diff --git a/registry/registry.go b/registry/registry.go
index 1f8f2cbe..15eb9410 100644
--- a/registry/registry.go
+++ b/registry/registry.go
@@ -100,12 +100,29 @@ var ServeCmd = &cobra.Command{
 			cmd.Usage()
 			os.Exit(1)
 		}
+
+		if config.HTTP.Debug.Addr != "" {
+			go func(addr string) {
+				logrus.Infof("debug server listening %v", addr)
+				if err := http.ListenAndServe(addr, nil); err != nil {
+					logrus.Fatalf("error listening on debug interface: %v", err)
+				}
+			}(config.HTTP.Debug.Addr)
+		}
+
 		registry, err := NewRegistry(ctx, config)
 		if err != nil {
 			logrus.Fatalln(err)
 		}
 
-		configureDebugServer(config)
+		if config.HTTP.Debug.Prometheus.Enabled {
+			path := config.HTTP.Debug.Prometheus.Path
+			if path == "" {
+				path = "/metrics"
+			}
+			logrus.Info("providing prometheus metrics on ", path)
+			http.Handle(path, metrics.Handler())
+		}
 
 		if err = registry.ListenAndServe(); err != nil {
 			logrus.Fatalln(err)
@@ -221,10 +238,11 @@ func (registry *Registry) ListenAndServe() error {
 		}
 
 		tlsConf := &tls.Config{
-			ClientAuth:   tls.NoClientCert,
-			NextProtos:   nextProtos(config),
-			MinVersion:   tlsMinVersion,
-			CipherSuites: tlsCipherSuites,
+			ClientAuth:               tls.NoClientCert,
+			NextProtos:               nextProtos(config),
+			MinVersion:               tlsMinVersion,
+			PreferServerCipherSuites: true,
+			CipherSuites:             tlsCipherSuites,
 		}
 
 		if config.HTTP.TLS.LetsEncrypt.CacheFile != "" {
@@ -261,7 +279,7 @@ func (registry *Registry) ListenAndServe() error {
 				}
 			}
 
-			for _, subj := range pool.Subjects() { //nolint:staticcheck // FIXME(thaJeztah): ignore SA1019: ac.(*accessController).rootCerts.Subjects has been deprecated since Go 1.18: if s was returned by SystemCertPool, Subjects will not include the system roots. (staticcheck)
+			for _, subj := range pool.Subjects() {
 				dcontext.GetLogger(registry.app).Debugf("CA Subject: %s", string(subj))
 			}
 
@@ -300,29 +318,6 @@ func (registry *Registry) ListenAndServe() error {
 	}
 }
 
-func configureDebugServer(config *configuration.Configuration) {
-	if config.HTTP.Debug.Addr != "" {
-		go func(addr string) {
-			logrus.Infof("debug server listening %v", addr)
-			if err := http.ListenAndServe(addr, nil); err != nil {
-				logrus.Fatalf("error listening on debug interface: %v", err)
-			}
-		}(config.HTTP.Debug.Addr)
-		configurePrometheus(config)
-	}
-}
-
-func configurePrometheus(config *configuration.Configuration) {
-	if config.HTTP.Debug.Prometheus.Enabled {
-		path := config.HTTP.Debug.Prometheus.Path
-		if path == "" {
-			path = "/metrics"
-		}
-		logrus.Info("providing prometheus metrics on ", path)
-		http.Handle(path, metrics.Handler())
-	}
-}
-
 func configureReporting(app *handlers.App) http.Handler {
 	var handler http.Handler = app
 
diff --git a/registry/storage/driver/inmemory/driver.go b/registry/storage/driver/inmemory/driver.go
index 6370ca63..f112fadc 100644
--- a/registry/storage/driver/inmemory/driver.go
+++ b/registry/storage/driver/inmemory/driver.go
@@ -251,8 +251,6 @@ func (d *driver) Walk(ctx context.Context, path string, f storagedriver.WalkFn)
 type writer struct {
 	d         *driver
 	f         *file
-	buffer    []byte
-	buffSize  int
 	closed    bool
 	committed bool
 	cancelled bool
@@ -276,17 +274,8 @@ func (w *writer) Write(p []byte) (int, error) {
 
 	w.d.mutex.Lock()
 	defer w.d.mutex.Unlock()
-	if cap(w.buffer) < len(p)+w.buffSize {
-		data := make([]byte, len(w.buffer), len(p)+w.buffSize)
-		copy(data, w.buffer)
-		w.buffer = data
-	}
-
-	w.buffer = w.buffer[:w.buffSize+len(p)]
-	n := copy(w.buffer[w.buffSize:w.buffSize+len(p)], p)
-	w.buffSize += n
 
-	return n, nil
+	return w.f.WriteAt(p, int64(len(w.f.data)))
 }
 
 func (w *writer) Size() int64 {
@@ -301,8 +290,6 @@ func (w *writer) Close() error {
 		return fmt.Errorf("already closed")
 	}
 	w.closed = true
-	w.flush()
-
 	return nil
 }
 
@@ -329,16 +316,5 @@ func (w *writer) Commit() error {
 		return fmt.Errorf("already cancelled")
 	}
 	w.committed = true
-	w.flush()
-
 	return nil
 }
-
-func (w *writer) flush() {
-	w.d.mutex.Lock()
-	defer w.d.mutex.Unlock()
-
-	w.f.WriteAt(w.buffer, int64(len(w.f.data)))
-	w.buffer = []byte{}
-	w.buffSize = 0
-}
diff --git a/registry/storage/manifeststore.go b/registry/storage/manifeststore.go
index 6b2f4e58..0daa92df 100644
--- a/registry/storage/manifeststore.go
+++ b/registry/storage/manifeststore.go
@@ -10,7 +10,7 @@ import (
 	"github.com/distribution/distribution/v3/manifest"
 	"github.com/distribution/distribution/v3/manifest/manifestlist"
 	"github.com/distribution/distribution/v3/manifest/ocischema"
-	"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	"github.com/distribution/distribution/v3/manifest/schema1"
 	"github.com/distribution/distribution/v3/manifest/schema2"
 	"github.com/opencontainers/go-digest"
 	v1 "github.com/opencontainers/image-spec/specs-go/v1"
@@ -130,7 +130,7 @@ func (ms *manifestStore) Put(ctx context.Context, manifest distribution.Manifest
 	dcontext.GetLogger(ms.ctx).Debug("(*manifestStore).Put")
 
 	switch manifest.(type) {
-	case *schema1.SignedManifest: //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	case *schema1.SignedManifest:
 		return ms.schema1Handler.Put(ctx, manifest, ms.skipDependencyVerification)
 	case *schema2.DeserializedManifest:
 		return ms.schema2Handler.Put(ctx, manifest, ms.skipDependencyVerification)
diff --git a/registry/storage/schema2manifesthandler.go b/registry/storage/schema2manifesthandler.go
index 7716289a..cdaa5e20 100644
--- a/registry/storage/schema2manifesthandler.go
+++ b/registry/storage/schema2manifesthandler.go
@@ -8,7 +8,7 @@ import (
 
 	"github.com/distribution/distribution/v3"
 	dcontext "github.com/distribution/distribution/v3/context"
-	"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	"github.com/distribution/distribution/v3/manifest/schema1"
 	"github.com/distribution/distribution/v3/manifest/schema2"
 	"github.com/opencontainers/go-digest"
 )
@@ -110,7 +110,7 @@ func (ms *schema2ManifestHandler) verifyManifest(ctx context.Context, mnfst sche
 					break
 				}
 			}
-		case schema2.MediaTypeManifest, schema1.MediaTypeManifest: //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+		case schema2.MediaTypeManifest, schema1.MediaTypeManifest:
 			var exists bool
 			exists, err = manifestService.Exists(ctx, descriptor.Digest)
 			if err != nil || !exists {
diff --git a/registry/storage/signedmanifesthandler.go b/registry/storage/signedmanifesthandler.go
index edb32e07..eb5b5742 100644
--- a/registry/storage/signedmanifesthandler.go
+++ b/registry/storage/signedmanifesthandler.go
@@ -7,7 +7,7 @@ import (
 
 	"github.com/distribution/distribution/v3"
 	dcontext "github.com/distribution/distribution/v3/context"
-	"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	"github.com/distribution/distribution/v3/manifest/schema1"
 	"github.com/distribution/distribution/v3/reference"
 	"github.com/docker/libtrust"
 	"github.com/opencontainers/go-digest"
@@ -49,7 +49,7 @@ func (ms *signedManifestHandler) Unmarshal(ctx context.Context, dgst digest.Dige
 		return nil, err
 	}
 
-	var sm schema1.SignedManifest //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	var sm schema1.SignedManifest
 	if err := json.Unmarshal(raw, &sm); err != nil {
 		return nil, err
 	}
@@ -59,7 +59,7 @@ func (ms *signedManifestHandler) Unmarshal(ctx context.Context, dgst digest.Dige
 func (ms *signedManifestHandler) Put(ctx context.Context, manifest distribution.Manifest, skipDependencyVerification bool) (digest.Digest, error) {
 	dcontext.GetLogger(ms.ctx).Debug("(*signedManifestHandler).Put")
 
-	sm, ok := manifest.(*schema1.SignedManifest) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	sm, ok := manifest.(*schema1.SignedManifest)
 	if !ok {
 		return "", fmt.Errorf("non-schema1 manifest put to signedManifestHandler: %T", manifest)
 	}
@@ -68,7 +68,7 @@ func (ms *signedManifestHandler) Put(ctx context.Context, manifest distribution.
 		return "", err
 	}
 
-	mt := schema1.MediaTypeManifest //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	mt := schema1.MediaTypeManifest
 	payload := sm.Canonical
 
 	revision, err := ms.blobStore.Put(ctx, mt, payload)
@@ -84,7 +84,7 @@ func (ms *signedManifestHandler) Put(ctx context.Context, manifest distribution.
 // perspective of the registry. It ensures that the signature is valid for the
 // enclosed payload. As a policy, the registry only tries to store valid
 // content, leaving trust policies of that content up to consumers.
-func (ms *signedManifestHandler) verifyManifest(ctx context.Context, mnfst schema1.SignedManifest, skipDependencyVerification bool) error { //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+func (ms *signedManifestHandler) verifyManifest(ctx context.Context, mnfst schema1.SignedManifest, skipDependencyVerification bool) error {
 	var errs distribution.ErrManifestVerification
 
 	if len(mnfst.Name) > reference.NameTotalLengthMax {
@@ -108,7 +108,7 @@ func (ms *signedManifestHandler) verifyManifest(ctx context.Context, mnfst schem
 			len(mnfst.History), len(mnfst.FSLayers)))
 	}
 
-	if _, err := schema1.Verify(&mnfst); err != nil { //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	if _, err := schema1.Verify(&mnfst); err != nil {
 		switch err {
 		case libtrust.ErrMissingSignatureKey, libtrust.ErrInvalidJSONContent, libtrust.ErrMissingSignatureKey:
 			errs = append(errs, distribution.ErrManifestUnverified{})
@@ -122,7 +122,7 @@ func (ms *signedManifestHandler) verifyManifest(ctx context.Context, mnfst schem
 	}
 
 	if !skipDependencyVerification {
-		for _, fsLayer := range mnfst.References() { //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+		for _, fsLayer := range mnfst.References() {
 			_, err := ms.repository.Blobs(ctx).Stat(ctx, fsLayer.Digest)
 			if err != nil {
 				if err != distribution.ErrBlobUnknown {


Test patch:
diff --git a/configuration/configuration_test.go b/configuration/configuration_test.go
index 23ab353e..6f8f021c 100644
--- a/configuration/configuration_test.go
+++ b/configuration/configuration_test.go
@@ -70,9 +70,6 @@ var configStruct = Configuration{
 			},
 		},
 	},
-	Catalog: Catalog{
-		MaxEntries: 1000,
-	},
 	HTTP: struct {
 		Addr         string        `yaml:"addr,omitempty"`
 		Net          string        `yaml:"net,omitempty"`
@@ -524,7 +521,6 @@ func copyConfig(config Configuration) *Configuration {
 	configCopy.Version = MajorMinorVersion(config.Version.Major(), config.Version.Minor())
 	configCopy.Loglevel = config.Loglevel
 	configCopy.Log = config.Log
-	configCopy.Catalog = config.Catalog
 	configCopy.Log.Fields = make(map[string]interface{}, len(config.Log.Fields))
 	for k, v := range config.Log.Fields {
 		configCopy.Log.Fields[k] = v
diff --git a/context/http_test.go b/context/http_test.go
index 5c741d59..69682966 100644
--- a/context/http_test.go
+++ b/context/http_test.go
@@ -22,7 +22,7 @@ func TestWithRequest(t *testing.T) {
 	req.Header.Set("User-Agent", "test/0.1")
 
 	ctx := WithRequest(Background(), &req)
-	for _, tc := range []struct {
+	for _, testcase := range []struct {
 		key      string
 		expected interface{}
 	}{
@@ -61,18 +61,18 @@ func TestWithRequest(t *testing.T) {
 			key: "http.request.startedat",
 		},
 	} {
-		v := ctx.Value(tc.key)
+		v := ctx.Value(testcase.key)
 
 		if v == nil {
-			t.Fatalf("value not found for %q", tc.key)
+			t.Fatalf("value not found for %q", testcase.key)
 		}
 
-		if tc.expected != nil && v != tc.expected {
-			t.Fatalf("%s: %v != %v", tc.key, v, tc.expected)
+		if testcase.expected != nil && v != testcase.expected {
+			t.Fatalf("%s: %v != %v", testcase.key, v, testcase.expected)
 		}
 
 		// Key specific checks!
-		switch tc.key {
+		switch testcase.key {
 		case "http.request.id":
 			if _, ok := v.(string); !ok {
 				t.Fatalf("request id not a string: %v", v)
@@ -195,7 +195,7 @@ func TestWithVars(t *testing.T) {
 	}
 
 	ctx := WithVars(Background(), &req)
-	for _, tc := range []struct {
+	for _, testcase := range []struct {
 		key      string
 		expected interface{}
 	}{
@@ -212,10 +212,10 @@ func TestWithVars(t *testing.T) {
 			expected: "qwer",
 		},
 	} {
-		v := ctx.Value(tc.key)
+		v := ctx.Value(testcase.key)
 
-		if !reflect.DeepEqual(v, tc.expected) {
-			t.Fatalf("%q: %v != %v", tc.key, v, tc.expected)
+		if !reflect.DeepEqual(v, testcase.expected) {
+			t.Fatalf("%q: %v != %v", testcase.key, v, testcase.expected)
 		}
 	}
 }
diff --git a/context/trace_test.go b/context/trace_test.go
index 4ee530bf..f973f9a4 100644
--- a/context/trace_test.go
+++ b/context/trace_test.go
@@ -1,6 +1,7 @@
 package context
 
 import (
+	"context"
 	"runtime"
 	"testing"
 	"time"
@@ -8,7 +9,6 @@ import (
 
 // TestWithTrace ensures that tracing has the expected values in the context.
 func TestWithTrace(t *testing.T) {
-	t.Parallel()
 	pc, file, _, _ := runtime.Caller(0) // get current caller.
 	f := runtime.FuncForPC(pc)
 
@@ -36,29 +36,12 @@ func TestWithTrace(t *testing.T) {
 	ctx, done := WithTrace(Background())
 	defer done("this will be emitted at end of test")
 
-	tests := append(base, valueTestCase{
+	checkContextForValues(ctx, t, append(base, valueTestCase{
 		key:      "trace.func",
 		expected: f.Name(),
-	})
-	for _, tc := range tests {
-		tc := tc
-		t.Run(tc.key, func(t *testing.T) {
-			t.Parallel()
-			v := ctx.Value(tc.key)
-			if tc.notnilorempty {
-				if v == nil || v == "" {
-					t.Fatalf("value was nil or empty: %#v", v)
-				}
-				return
-			}
-
-			if v != tc.expected {
-				t.Fatalf("unexpected value: %v != %v", v, tc.expected)
-			}
-		})
-	}
+	}))
 
-	tracedFn := func() {
+	traced := func() {
 		parentID := ctx.Value("trace.id") // ensure the parent trace id is correct.
 
 		pc, _, _, _ := runtime.Caller(0) // get current caller.
@@ -66,32 +49,15 @@ func TestWithTrace(t *testing.T) {
 		ctx, done := WithTrace(ctx)
 		defer done("this should be subordinate to the other trace")
 		time.Sleep(time.Second)
-		tests := append(base, valueTestCase{
+		checkContextForValues(ctx, t, append(base, valueTestCase{
 			key:      "trace.func",
 			expected: f.Name(),
 		}, valueTestCase{
 			key:      "trace.parent.id",
 			expected: parentID,
-		})
-		for _, tc := range tests {
-			tc := tc
-			t.Run(tc.key, func(t *testing.T) {
-				t.Parallel()
-				v := ctx.Value(tc.key)
-				if tc.notnilorempty {
-					if v == nil || v == "" {
-						t.Fatalf("value was nil or empty: %#v", v)
-					}
-					return
-				}
-
-				if v != tc.expected {
-					t.Fatalf("unexpected value: %v != %v", v, tc.expected)
-				}
-			})
-		}
+		}))
 	}
-	tracedFn()
+	traced()
 
 	time.Sleep(time.Second)
 }
@@ -101,3 +67,19 @@ type valueTestCase struct {
 	expected      interface{}
 	notnilorempty bool // just check not empty/not nil
 }
+
+func checkContextForValues(ctx context.Context, t *testing.T, values []valueTestCase) {
+	for _, testcase := range values {
+		v := ctx.Value(testcase.key)
+		if testcase.notnilorempty {
+			if v == nil || v == "" {
+				t.Fatalf("value was nil or empty for %q: %#v", testcase.key, v)
+			}
+			continue
+		}
+
+		if v != testcase.expected {
+			t.Fatalf("unexpected value for key %q: %v != %v", testcase.key, v, testcase.expected)
+		}
+	}
+}
diff --git a/manifest/schema2/builder_test.go b/manifest/schema2/builder_test.go
index aa9f17c1..039246a3 100644
--- a/manifest/schema2/builder_test.go
+++ b/manifest/schema2/builder_test.go
@@ -9,28 +9,6 @@ import (
 	"github.com/opencontainers/go-digest"
 )
 
-type mockBlobService struct {
-	descriptors map[digest.Digest]distribution.Descriptor
-	distribution.BlobService
-}
-
-func (bs *mockBlobService) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
-	if descriptor, ok := bs.descriptors[dgst]; ok {
-		return descriptor, nil
-	}
-	return distribution.Descriptor{}, distribution.ErrBlobUnknown
-}
-
-func (bs *mockBlobService) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) {
-	d := distribution.Descriptor{
-		MediaType: "application/octet-stream",
-		Digest:    digest.FromBytes(p),
-		Size:      int64(len(p)),
-	}
-	bs.descriptors[d.Digest] = d
-	return d, nil
-}
-
 func TestBuilder(t *testing.T) {
 	imgJSON := []byte(`{
     "architecture": "amd64",
@@ -150,8 +128,13 @@ func TestBuilder(t *testing.T) {
 		},
 	}
 
-	bs := &mockBlobService{descriptors: make(map[digest.Digest]distribution.Descriptor)}
-	builder := NewManifestBuilder(bs, MediaTypeImageConfig, imgJSON)
+	d := distribution.Descriptor{
+		Digest:    digest.FromBytes(imgJSON),
+		Size:      int64(len(imgJSON)),
+		MediaType: MediaTypeImageConfig,
+	}
+
+	builder := NewManifestBuilder(d, imgJSON)
 
 	for _, d := range descriptors {
 		if err := builder.AppendReference(d); err != nil {
@@ -164,12 +147,6 @@ func TestBuilder(t *testing.T) {
 		t.Fatalf("Build returned error: %v", err)
 	}
 
-	// Check that the config was put in the blob store
-	_, err = bs.Stat(context.Background(), configDigest)
-	if err != nil {
-		t.Fatal("config was not put in the blob store")
-	}
-
 	manifest := built.(*DeserializedManifest).Manifest
 
 	if manifest.Versioned.SchemaVersion != 2 {
diff --git a/notifications/bridge_test.go b/notifications/bridge_test.go
index 65b09a07..7d479f6c 100644
--- a/notifications/bridge_test.go
+++ b/notifications/bridge_test.go
@@ -4,7 +4,7 @@ import (
 	"testing"
 
 	"github.com/distribution/distribution/v3"
-	"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	"github.com/distribution/distribution/v3/manifest/schema1"
 	"github.com/distribution/distribution/v3/reference"
 	v2 "github.com/distribution/distribution/v3/registry/api/v2"
 	"github.com/distribution/distribution/v3/uuid"
@@ -27,7 +27,7 @@ var (
 		Name: "test",
 	}
 	request = RequestRecord{}
-	layers  = []schema1.FSLayer{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	layers  = []schema1.FSLayer{
 		{
 			BlobSum: "asdf",
 		},
@@ -35,13 +35,13 @@ var (
 			BlobSum: "qwer",
 		},
 	}
-	m = schema1.Manifest{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	m = schema1.Manifest{
 		Name:     repo,
 		Tag:      "latest",
 		FSLayers: layers,
 	}
 
-	sm      *schema1.SignedManifest //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	sm      *schema1.SignedManifest
 	payload []byte
 	dgst    digest.Digest
 )
@@ -152,7 +152,7 @@ func createTestEnv(t *testing.T, fn testSinkFn) Listener {
 		t.Fatalf("error generating private key: %v", err)
 	}
 
-	sm, err = schema1.Sign(&m, pk) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	sm, err = schema1.Sign(&m, pk)
 	if err != nil {
 		t.Fatalf("error signing manifest: %v", err)
 	}
diff --git a/notifications/event_test.go b/notifications/event_test.go
index 59a86fd5..41562717 100644
--- a/notifications/event_test.go
+++ b/notifications/event_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	"github.com/distribution/distribution/v3/manifest/schema1"
 )
 
 // TestEventJSONFormat provides silly test to detect if the event format or
@@ -116,7 +116,7 @@ func TestEventEnvelopeJSONFormat(t *testing.T) {
 
 	manifestPush := prototype
 	manifestPush.ID = "asdf-asdf-asdf-asdf-0"
-	manifestPush.Target.MediaType = schema1.MediaTypeSignedManifest //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	manifestPush.Target.MediaType = schema1.MediaTypeSignedManifest
 	manifestPush.Target.Digest = "sha256:0123456789abcdef0"
 	manifestPush.Target.Size = 1
 	manifestPush.Target.Length = 1
diff --git a/notifications/http_test.go b/notifications/http_test.go
index fdcb6b5c..0d5ec4a5 100644
--- a/notifications/http_test.go
+++ b/notifications/http_test.go
@@ -13,7 +13,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	"github.com/distribution/distribution/v3/manifest/schema1"
 	events "github.com/docker/go-events"
 )
 
@@ -121,11 +121,11 @@ func TestHTTPSink(t *testing.T) {
 	}{
 		{
 			statusCode: http.StatusOK,
-			event:      createTestEvent("push", "library/test", schema1.MediaTypeSignedManifest), //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+			event:      createTestEvent("push", "library/test", schema1.MediaTypeSignedManifest),
 		},
 		{
 			statusCode: http.StatusOK,
-			event:      createTestEvent("push", "library/test", schema1.MediaTypeSignedManifest), //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+			event:      createTestEvent("push", "library/test", schema1.MediaTypeSignedManifest),
 		},
 		{
 			statusCode: http.StatusOK,
diff --git a/notifications/listener_test.go b/notifications/listener_test.go
index 9e588318..cf554b6d 100644
--- a/notifications/listener_test.go
+++ b/notifications/listener_test.go
@@ -8,7 +8,7 @@ import (
 	"github.com/distribution/distribution/v3"
 	"github.com/distribution/distribution/v3/context"
 	"github.com/distribution/distribution/v3/manifest"
-	"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	"github.com/distribution/distribution/v3/manifest/schema1"
 	"github.com/distribution/distribution/v3/reference"
 	"github.com/distribution/distribution/v3/registry/storage"
 	"github.com/distribution/distribution/v3/registry/storage/cache/memory"
@@ -125,7 +125,7 @@ func checkExerciseRepository(t *testing.T, repository distribution.Repository, r
 	tag := "thetag"
 	// todo: change this to use Builder
 
-	m := schema1.Manifest{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	m := schema1.Manifest{
 		Versioned: manifest.Versioned{
 			SchemaVersion: 1,
 		},
@@ -159,10 +159,10 @@ func checkExerciseRepository(t *testing.T, repository distribution.Repository, r
 			t.Fatalf("unexpected error finishing upload: %v", err)
 		}
 
-		m.FSLayers = append(m.FSLayers, schema1.FSLayer{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+		m.FSLayers = append(m.FSLayers, schema1.FSLayer{
 			BlobSum: dgst,
 		})
-		m.History = append(m.History, schema1.History{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+		m.History = append(m.History, schema1.History{
 			V1Compatibility: "",
 		})
 
@@ -179,7 +179,7 @@ func checkExerciseRepository(t *testing.T, repository distribution.Repository, r
 		t.Fatalf("unexpected error generating key: %v", err)
 	}
 
-	sm, err := schema1.Sign(&m, pk) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	sm, err := schema1.Sign(&m, pk)
 	if err != nil {
 		t.Fatalf("unexpected error signing manifest: %v", err)
 	}
diff --git a/notifications/sinks_test.go b/notifications/sinks_test.go
index de3eae3f..b1e51d5b 100644
--- a/notifications/sinks_test.go
+++ b/notifications/sinks_test.go
@@ -73,49 +73,49 @@ func TestIgnoredSink(t *testing.T) {
 		expected         events.Event
 	}
 
-	tests := []testcase{
-		{expected: blob},
-		{ignoreMediaTypes: []string{"other"}, ignoreActions: []string{"other"}, expected: blob},
-		{ignoreMediaTypes: []string{"blob", "manifest"}, ignoreActions: []string{"other"}},
-		{ignoreMediaTypes: []string{"other"}, ignoreActions: []string{"pull"}, expected: blob},
-		{ignoreMediaTypes: []string{"other"}, ignoreActions: []string{"pull", "push"}},
+	cases := []testcase{
+		{nil, nil, blob},
+		{[]string{"other"}, []string{"other"}, blob},
+		{[]string{"blob", "manifest"}, []string{"other"}, nil},
+		{[]string{"other"}, []string{"pull"}, blob},
+		{[]string{"other"}, []string{"pull", "push"}, nil},
 	}
 
-	for _, tc := range tests {
+	for _, c := range cases {
 		ts := &testSink{}
-		s := newIgnoredSink(ts, tc.ignoreMediaTypes, tc.ignoreActions)
+		s := newIgnoredSink(ts, c.ignoreMediaTypes, c.ignoreActions)
 
 		if err := s.Write(blob); err != nil {
 			t.Fatalf("error writing event: %v", err)
 		}
 
 		ts.mu.Lock()
-		if !reflect.DeepEqual(ts.event, tc.expected) {
-			t.Fatalf("unexpected event: %#v != %#v", ts.event, tc.expected)
+		if !reflect.DeepEqual(ts.event, c.expected) {
+			t.Fatalf("unexpected event: %#v != %#v", ts.event, c.expected)
 		}
 		ts.mu.Unlock()
 	}
 
-	tests = []testcase{
-		{expected: manifest},
-		{ignoreMediaTypes: []string{"other"}, ignoreActions: []string{"other"}, expected: manifest},
-		{ignoreMediaTypes: []string{"blob"}, ignoreActions: []string{"other"}, expected: manifest},
-		{ignoreMediaTypes: []string{"blob", "manifest"}, ignoreActions: []string{"other"}},
-		{ignoreMediaTypes: []string{"other"}, ignoreActions: []string{"push"}, expected: manifest},
-		{ignoreMediaTypes: []string{"other"}, ignoreActions: []string{"pull", "push"}},
+	cases = []testcase{
+		{nil, nil, manifest},
+		{[]string{"other"}, []string{"other"}, manifest},
+		{[]string{"blob"}, []string{"other"}, manifest},
+		{[]string{"blob", "manifest"}, []string{"other"}, nil},
+		{[]string{"other"}, []string{"push"}, manifest},
+		{[]string{"other"}, []string{"pull", "push"}, nil},
 	}
 
-	for _, tc := range tests {
+	for _, c := range cases {
 		ts := &testSink{}
-		s := newIgnoredSink(ts, tc.ignoreMediaTypes, tc.ignoreActions)
+		s := newIgnoredSink(ts, c.ignoreMediaTypes, c.ignoreActions)
 
 		if err := s.Write(manifest); err != nil {
 			t.Fatalf("error writing event: %v", err)
 		}
 
 		ts.mu.Lock()
-		if !reflect.DeepEqual(ts.event, tc.expected) {
-			t.Fatalf("unexpected event: %#v != %#v", ts.event, tc.expected)
+		if !reflect.DeepEqual(ts.event, c.expected) {
+			t.Fatalf("unexpected event: %#v != %#v", ts.event, c.expected)
 		}
 		ts.mu.Unlock()
 	}
diff --git a/reference/normalize_test.go b/reference/normalize_test.go
index a973927b..22803672 100644
--- a/reference/normalize_test.go
+++ b/reference/normalize_test.go
@@ -146,7 +146,7 @@ func TestParseRepositoryInfo(t *testing.T) {
 		RemoteName, FamiliarName, FullName, AmbiguousName, Domain string
 	}
 
-	tests := []tcase{
+	tcases := []tcase{
 		{
 			RemoteName:    "fooo/bar",
 			FamiliarName:  "fooo/bar",
@@ -261,7 +261,7 @@ func TestParseRepositoryInfo(t *testing.T) {
 		},
 	}
 
-	for i, tc := range tests {
+	for i, tc := range tcases {
 		tc := tc
 		refStrings := []string{tc.FamiliarName, tc.FullName}
 		if tc.AmbiguousName != "" {
@@ -269,7 +269,6 @@ func TestParseRepositoryInfo(t *testing.T) {
 		}
 
 		for _, r := range refStrings {
-			r := r
 			t.Run(strconv.Itoa(i)+"/"+r, func(t *testing.T) {
 				t.Parallel()
 				named, err := ParseNormalizedNamed(r)
@@ -368,7 +367,7 @@ func equalReference(r1, r2 Reference) bool {
 
 func TestParseAnyReference(t *testing.T) {
 	t.Parallel()
-	tests := []struct {
+	tcases := []struct {
 		Reference  string
 		Equivalent string
 		Expected   Reference
@@ -433,37 +432,33 @@ func TestParseAnyReference(t *testing.T) {
 		},
 	}
 
-	for _, tc := range tests {
-		tc := tc
-		t.Run(tc.Reference, func(t *testing.T) {
-			t.Parallel()
-			var ref Reference
-			var err error
-			ref, err = ParseAnyReference(tc.Reference)
-			if err != nil {
-				t.Fatalf("Error parsing reference %s: %v", tc.Reference, err)
-			}
-			if ref.String() != tc.Equivalent {
-				t.Fatalf("Unexpected string: %s, expected %s", ref.String(), tc.Equivalent)
-			}
+	for _, tcase := range tcases {
+		var ref Reference
+		var err error
+		ref, err = ParseAnyReference(tcase.Reference)
+		if err != nil {
+			t.Fatalf("Error parsing reference %s: %v", tcase.Reference, err)
+		}
+		if ref.String() != tcase.Equivalent {
+			t.Fatalf("Unexpected string: %s, expected %s", ref.String(), tcase.Equivalent)
+		}
 
-			expected := tc.Expected
-			if expected == nil {
-				expected, err = Parse(tc.Equivalent)
-				if err != nil {
-					t.Fatalf("Error parsing reference %s: %v", tc.Equivalent, err)
-				}
-			}
-			if !equalReference(ref, expected) {
-				t.Errorf("Unexpected reference %#v, expected %#v", ref, expected)
+		expected := tcase.Expected
+		if expected == nil {
+			expected, err = Parse(tcase.Equivalent)
+			if err != nil {
+				t.Fatalf("Error parsing reference %s: %v", tcase.Equivalent, err)
 			}
-		})
+		}
+		if !equalReference(ref, expected) {
+			t.Errorf("Unexpected reference %#v, expected %#v", ref, expected)
+		}
 	}
 }
 
 func TestNormalizedSplitHostname(t *testing.T) {
 	t.Parallel()
-	tests := []struct {
+	testcases := []struct {
 		input  string
 		domain string
 		name   string
@@ -524,22 +519,23 @@ func TestNormalizedSplitHostname(t *testing.T) {
 			name:   "library/foo/bar",
 		},
 	}
-	for _, tc := range tests {
-		tc := tc
-		t.Run(tc.input, func(t *testing.T) {
-			t.Parallel()
-			named, err := ParseNormalizedNamed(tc.input)
-			if err != nil {
-				t.Errorf("error parsing name: %s", err)
-			}
-			domain, name := SplitHostname(named) //nolint:staticcheck // Ignore SA1019: SplitHostname is deprecated.
-			if domain != tc.domain {
-				t.Errorf("unexpected domain: got %q, expected %q", domain, tc.domain)
-			}
-			if name != tc.name {
-				t.Errorf("unexpected name: got %q, expected %q", name, tc.name)
-			}
-		})
+	for _, testcase := range testcases {
+		failf := func(format string, v ...interface{}) {
+			t.Logf(strconv.Quote(testcase.input)+": "+format, v...)
+			t.Fail()
+		}
+
+		named, err := ParseNormalizedNamed(testcase.input)
+		if err != nil {
+			failf("error parsing name: %s", err)
+		}
+		domain, name := SplitHostname(named)
+		if domain != testcase.domain {
+			failf("unexpected domain: got %q, expected %q", domain, testcase.domain)
+		}
+		if name != testcase.name {
+			failf("unexpected name: got %q, expected %q", name, testcase.name)
+		}
 	}
 }
 
@@ -557,7 +553,7 @@ func TestMatchError(t *testing.T) {
 
 func TestMatch(t *testing.T) {
 	t.Parallel()
-	tests := []struct {
+	matchCases := []struct {
 		reference string
 		pattern   string
 		expected  bool
@@ -608,28 +604,24 @@ func TestMatch(t *testing.T) {
 			expected:  true,
 		},
 	}
-	for _, tc := range tests {
-		tc := tc
-		t.Run(tc.reference, func(t *testing.T) {
-			t.Parallel()
-			named, err := ParseAnyReference(tc.reference)
-			if err != nil {
-				t.Fatal(err)
-			}
-			actual, err := FamiliarMatch(tc.pattern, named)
-			if err != nil {
-				t.Fatal(err)
-			}
-			if actual != tc.expected {
-				t.Fatalf("expected %s match %s to be %v, was %v", tc.reference, tc.pattern, tc.expected, actual)
-			}
-		})
+	for _, c := range matchCases {
+		named, err := ParseAnyReference(c.reference)
+		if err != nil {
+			t.Fatal(err)
+		}
+		actual, err := FamiliarMatch(c.pattern, named)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if actual != c.expected {
+			t.Fatalf("expected %s match %s to be %v, was %v", c.reference, c.pattern, c.expected, actual)
+		}
 	}
 }
 
 func TestParseDockerRef(t *testing.T) {
 	t.Parallel()
-	tests := []struct {
+	testcases := []struct {
 		name     string
 		input    string
 		expected string
@@ -690,17 +682,17 @@ func TestParseDockerRef(t *testing.T) {
 			expected: "gcr.io/library/busybox@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582",
 		},
 	}
-	for _, tc := range tests {
-		tc := tc
-		t.Run(tc.name, func(t *testing.T) {
+	for _, test := range testcases {
+		test := test
+		t.Run(test.name, func(t *testing.T) {
 			t.Parallel()
-			normalized, err := ParseDockerRef(tc.input)
+			normalized, err := ParseDockerRef(test.input)
 			if err != nil {
 				t.Fatal(err)
 			}
 			output := normalized.String()
-			if output != tc.expected {
-				t.Fatalf("expected %q to be parsed as %v, got %v", tc.input, tc.expected, output)
+			if output != test.expected {
+				t.Fatalf("expected %q to be parsed as %v, got %v", test.input, test.expected, output)
 			}
 			_, err = Parse(output)
 			if err != nil {
diff --git a/reference/reference_test.go b/reference/reference_test.go
index d5a897c7..5d6878cf 100644
--- a/reference/reference_test.go
+++ b/reference/reference_test.go
@@ -12,9 +12,9 @@ import (
 
 func TestReferenceParse(t *testing.T) {
 	t.Parallel()
-	// tests is a unified set of testcases for
+	// referenceTestcases is a unified set of testcases for
 	// testing the parsing of references
-	tests := []struct {
+	referenceTestcases := []struct {
 		// input is the repository name or name component testcase
 		input string
 		// err is the error expected from Parse, or nil
@@ -267,43 +267,43 @@ func TestReferenceParse(t *testing.T) {
 			err:   ErrReferenceInvalidFormat,
 		},
 	}
-	for _, tc := range tests {
-		tc := tc
-		t.Run(tc.input, func(t *testing.T) {
+	for _, testcase := range referenceTestcases {
+		testcase := testcase
+		t.Run(testcase.input, func(t *testing.T) {
 			t.Parallel()
-			repo, err := Parse(tc.input)
-			if tc.err != nil {
+			repo, err := Parse(testcase.input)
+			if testcase.err != nil {
 				if err == nil {
-					t.Errorf("missing expected error: %v", tc.err)
-				} else if tc.err != err {
-					t.Errorf("mismatched error: got %v, expected %v", err, tc.err)
+					t.Errorf("missing expected error: %v", testcase.err)
+				} else if testcase.err != err {
+					t.Errorf("mismatched error: got %v, expected %v", err, testcase.err)
 				}
 				return
 			} else if err != nil {
 				t.Errorf("unexpected parse error: %v", err)
 				return
 			}
-			if repo.String() != tc.input {
-				t.Errorf("mismatched repo: got %q, expected %q", repo.String(), tc.input)
+			if repo.String() != testcase.input {
+				t.Errorf("mismatched repo: got %q, expected %q", repo.String(), testcase.input)
 			}
 
 			if named, ok := repo.(Named); ok {
-				if named.Name() != tc.repository {
-					t.Errorf("unexpected repository: got %q, expected %q", named.Name(), tc.repository)
+				if named.Name() != testcase.repository {
+					t.Errorf("unexpected repository: got %q, expected %q", named.Name(), testcase.repository)
 				}
 				domain, _ := SplitHostname(named)
-				if domain != tc.domain {
-					t.Errorf("unexpected domain: got %q, expected %q", domain, tc.domain)
+				if domain != testcase.domain {
+					t.Errorf("unexpected domain: got %q, expected %q", domain, testcase.domain)
 				}
-			} else if tc.repository != "" || tc.domain != "" {
+			} else if testcase.repository != "" || testcase.domain != "" {
 				t.Errorf("expected named type, got %T", repo)
 			}
 
 			tagged, ok := repo.(Tagged)
-			if tc.tag != "" {
+			if testcase.tag != "" {
 				if ok {
-					if tagged.Tag() != tc.tag {
-						t.Errorf("unexpected tag: got %q, expected %q", tagged.Tag(), tc.tag)
+					if tagged.Tag() != testcase.tag {
+						t.Errorf("unexpected tag: got %q, expected %q", tagged.Tag(), testcase.tag)
 					}
 				} else {
 					t.Errorf("expected tagged type, got %T", repo)
@@ -313,10 +313,10 @@ func TestReferenceParse(t *testing.T) {
 			}
 
 			digested, ok := repo.(Digested)
-			if tc.digest != "" {
+			if testcase.digest != "" {
 				if ok {
-					if digested.Digest().String() != tc.digest {
-						t.Errorf("unexpected digest: got %q, expected %q", digested.Digest().String(), tc.digest)
+					if digested.Digest().String() != testcase.digest {
+						t.Errorf("unexpected digest: got %q, expected %q", digested.Digest().String(), testcase.digest)
 					}
 				} else {
 					t.Errorf("expected digested type, got %T", repo)
@@ -332,7 +332,7 @@ func TestReferenceParse(t *testing.T) {
 // should succeed are covered by TestSplitHostname, below.
 func TestWithNameFailure(t *testing.T) {
 	t.Parallel()
-	tests := []struct {
+	testcases := []struct {
 		input string
 		err   error
 	}{
@@ -361,13 +361,13 @@ func TestWithNameFailure(t *testing.T) {
 			err:   ErrReferenceInvalidFormat,
 		},
 	}
-	for _, tc := range tests {
-		tc := tc
-		t.Run(tc.input, func(t *testing.T) {
+	for _, testcase := range testcases {
+		testcase := testcase
+		t.Run(testcase.input, func(t *testing.T) {
 			t.Parallel()
-			_, err := WithName(tc.input)
+			_, err := WithName(testcase.input)
 			if err == nil {
-				t.Errorf("no error parsing name. expected: %s", tc.err)
+				t.Errorf("no error parsing name. expected: %s", testcase.err)
 			}
 		})
 	}
@@ -375,7 +375,7 @@ func TestWithNameFailure(t *testing.T) {
 
 func TestSplitHostname(t *testing.T) {
 	t.Parallel()
-	tests := []struct {
+	testcases := []struct {
 		input  string
 		domain string
 		name   string
@@ -411,20 +411,20 @@ func TestSplitHostname(t *testing.T) {
 			name:   "foo",
 		},
 	}
-	for _, tc := range tests {
-		tc := tc
-		t.Run(tc.input, func(t *testing.T) {
+	for _, testcase := range testcases {
+		testcase := testcase
+		t.Run(testcase.input, func(t *testing.T) {
 			t.Parallel()
-			named, err := WithName(tc.input)
+			named, err := WithName(testcase.input)
 			if err != nil {
 				t.Errorf("error parsing name: %s", err)
 			}
 			domain, name := SplitHostname(named)
-			if domain != tc.domain {
-				t.Errorf("unexpected domain: got %q, expected %q", domain, tc.domain)
+			if domain != testcase.domain {
+				t.Errorf("unexpected domain: got %q, expected %q", domain, testcase.domain)
 			}
-			if name != tc.name {
-				t.Errorf("unexpected name: got %q, expected %q", name, tc.name)
+			if name != testcase.name {
+				t.Errorf("unexpected name: got %q, expected %q", name, testcase.name)
 			}
 		})
 	}
@@ -437,7 +437,7 @@ type serializationType struct {
 
 func TestSerialization(t *testing.T) {
 	t.Parallel()
-	tests := []struct {
+	testcases := []struct {
 		description string
 		input       string
 		name        string
@@ -467,13 +467,13 @@ func TestSerialization(t *testing.T) {
 			digest:      "sha256:1234567890098765432112345667890098765432112345667890098765432112",
 		},
 	}
-	for _, tc := range tests {
-		tc := tc
-		t.Run(tc.description, func(t *testing.T) {
+	for _, testcase := range testcases {
+		testcase := testcase
+		t.Run(testcase.description, func(t *testing.T) {
 			t.Parallel()
 			m := map[string]string{
-				"Description": tc.description,
-				"Field":       tc.input,
+				"Description": testcase.description,
+				"Field":       testcase.input,
 			}
 			b, err := json.Marshal(m)
 			if err != nil {
@@ -482,37 +482,37 @@ func TestSerialization(t *testing.T) {
 			st := serializationType{}
 
 			if err := json.Unmarshal(b, &st); err != nil {
-				if tc.err == nil {
+				if testcase.err == nil {
 					t.Errorf("error unmarshalling: %v", err)
 				}
-				if err != tc.err {
-					t.Errorf("wrong error, expected %v, got %v", tc.err, err)
+				if err != testcase.err {
+					t.Errorf("wrong error, expected %v, got %v", testcase.err, err)
 				}
 
 				return
-			} else if tc.err != nil {
-				t.Errorf("expected error unmarshalling: %v", tc.err)
+			} else if testcase.err != nil {
+				t.Errorf("expected error unmarshalling: %v", testcase.err)
 			}
 
-			if st.Description != tc.description {
-				t.Errorf("wrong description, expected %q, got %q", tc.description, st.Description)
+			if st.Description != testcase.description {
+				t.Errorf("wrong description, expected %q, got %q", testcase.description, st.Description)
 			}
 
 			ref := st.Field.Reference()
 
 			if named, ok := ref.(Named); ok {
-				if named.Name() != tc.name {
-					t.Errorf("unexpected repository: got %q, expected %q", named.Name(), tc.name)
+				if named.Name() != testcase.name {
+					t.Errorf("unexpected repository: got %q, expected %q", named.Name(), testcase.name)
 				}
-			} else if tc.name != "" {
+			} else if testcase.name != "" {
 				t.Errorf("expected named type, got %T", ref)
 			}
 
 			tagged, ok := ref.(Tagged)
-			if tc.tag != "" {
+			if testcase.tag != "" {
 				if ok {
-					if tagged.Tag() != tc.tag {
-						t.Errorf("unexpected tag: got %q, expected %q", tagged.Tag(), tc.tag)
+					if tagged.Tag() != testcase.tag {
+						t.Errorf("unexpected tag: got %q, expected %q", tagged.Tag(), testcase.tag)
 					}
 				} else {
 					t.Errorf("expected tagged type, got %T", ref)
@@ -522,10 +522,10 @@ func TestSerialization(t *testing.T) {
 			}
 
 			digested, ok := ref.(Digested)
-			if tc.digest != "" {
+			if testcase.digest != "" {
 				if ok {
-					if digested.Digest().String() != tc.digest {
-						t.Errorf("unexpected digest: got %q, expected %q", digested.Digest().String(), tc.digest)
+					if digested.Digest().String() != testcase.digest {
+						t.Errorf("unexpected digest: got %q, expected %q", digested.Digest().String(), testcase.digest)
 					}
 				} else {
 					t.Errorf("expected digested type, got %T", ref)
@@ -535,7 +535,7 @@ func TestSerialization(t *testing.T) {
 			}
 
 			st = serializationType{
-				Description: tc.description,
+				Description: testcase.description,
 				Field:       AsField(ref),
 			}
 
@@ -560,7 +560,7 @@ func TestSerialization(t *testing.T) {
 
 func TestWithTag(t *testing.T) {
 	t.Parallel()
-	tests := []struct {
+	testcases := []struct {
 		name     string
 		digest   digest.Digest
 		tag      string
@@ -593,28 +593,28 @@ func TestWithTag(t *testing.T) {
 			combined: "test.com:8000/foo:TAG5@sha256:1234567890098765432112345667890098765",
 		},
 	}
-	for _, tc := range tests {
-		tc := tc
-		t.Run(tc.combined, func(t *testing.T) {
+	for _, testcase := range testcases {
+		testcase := testcase
+		t.Run(testcase.combined, func(t *testing.T) {
 			t.Parallel()
-			named, err := WithName(tc.name)
+			named, err := WithName(testcase.name)
 			if err != nil {
 				t.Errorf("error parsing name: %s", err)
 			}
-			if tc.digest != "" {
-				canonical, err := WithDigest(named, tc.digest)
+			if testcase.digest != "" {
+				canonical, err := WithDigest(named, testcase.digest)
 				if err != nil {
 					t.Errorf("error adding digest")
 				}
 				named = canonical
 			}
 
-			tagged, err := WithTag(named, tc.tag)
+			tagged, err := WithTag(named, testcase.tag)
 			if err != nil {
 				t.Errorf("WithTag failed: %s", err)
 			}
-			if tagged.String() != tc.combined {
-				t.Errorf("unexpected: got %q, expected %q", tagged.String(), tc.combined)
+			if tagged.String() != testcase.combined {
+				t.Errorf("unexpected: got %q, expected %q", tagged.String(), testcase.combined)
 			}
 		})
 	}
@@ -622,7 +622,7 @@ func TestWithTag(t *testing.T) {
 
 func TestWithDigest(t *testing.T) {
 	t.Parallel()
-	tests := []struct {
+	testcases := []struct {
 		name     string
 		digest   digest.Digest
 		tag      string
@@ -650,27 +650,27 @@ func TestWithDigest(t *testing.T) {
 			combined: "test.com:8000/foo:latest@sha256:1234567890098765432112345667890098765",
 		},
 	}
-	for _, tc := range tests {
-		tc := tc
-		t.Run(tc.combined, func(t *testing.T) {
+	for _, testcase := range testcases {
+		testcase := testcase
+		t.Run(testcase.combined, func(t *testing.T) {
 			t.Parallel()
-			named, err := WithName(tc.name)
+			named, err := WithName(testcase.name)
 			if err != nil {
 				t.Errorf("error parsing name: %s", err)
 			}
-			if tc.tag != "" {
-				tagged, err := WithTag(named, tc.tag)
+			if testcase.tag != "" {
+				tagged, err := WithTag(named, testcase.tag)
 				if err != nil {
 					t.Errorf("error adding tag")
 				}
 				named = tagged
 			}
-			digested, err := WithDigest(named, tc.digest)
+			digested, err := WithDigest(named, testcase.digest)
 			if err != nil {
 				t.Errorf("WithDigest failed: %s", err)
 			}
-			if digested.String() != tc.combined {
-				t.Errorf("unexpected: got %q, expected %q", digested.String(), tc.combined)
+			if digested.String() != testcase.combined {
+				t.Errorf("unexpected: got %q, expected %q", digested.String(), testcase.combined)
 			}
 		})
 	}
@@ -678,7 +678,7 @@ func TestWithDigest(t *testing.T) {
 
 func TestParseNamed(t *testing.T) {
 	t.Parallel()
-	tests := []struct {
+	testcases := []struct {
 		input  string
 		domain string
 		name   string
@@ -721,30 +721,30 @@ func TestParseNamed(t *testing.T) {
 			err:   ErrNameNotCanonical,
 		},
 	}
-	for _, tc := range tests {
-		tc := tc
-		t.Run(tc.input, func(t *testing.T) {
+	for _, testcase := range testcases {
+		testcase := testcase
+		t.Run(testcase.input, func(t *testing.T) {
 			t.Parallel()
-			named, err := ParseNamed(tc.input)
-			if err != nil && tc.err == nil {
+			named, err := ParseNamed(testcase.input)
+			if err != nil && testcase.err == nil {
 				t.Errorf("error parsing name: %s", err)
 				return
-			} else if err == nil && tc.err != nil {
-				t.Errorf("parsing succeeded: expected error %v", tc.err)
+			} else if err == nil && testcase.err != nil {
+				t.Errorf("parsing succeeded: expected error %v", testcase.err)
 				return
-			} else if err != tc.err {
-				t.Errorf("unexpected error %v, expected %v", err, tc.err)
+			} else if err != testcase.err {
+				t.Errorf("unexpected error %v, expected %v", err, testcase.err)
 				return
 			} else if err != nil {
 				return
 			}
 
 			domain, name := SplitHostname(named)
-			if domain != tc.domain {
-				t.Errorf("unexpected domain: got %q, expected %q", domain, tc.domain)
+			if domain != testcase.domain {
+				t.Errorf("unexpected domain: got %q, expected %q", domain, testcase.domain)
 			}
-			if name != tc.name {
-				t.Errorf("unexpected name: got %q, expected %q", name, tc.name)
+			if name != testcase.name {
+				t.Errorf("unexpected name: got %q, expected %q", name, testcase.name)
 			}
 		})
 	}
diff --git a/reference/regexp_test.go b/reference/regexp_test.go
index ca4680d3..44b33f01 100644
--- a/reference/regexp_test.go
+++ b/reference/regexp_test.go
@@ -36,7 +36,7 @@ func checkRegexp(t *testing.T, r *regexp.Regexp, m regexpMatch) {
 
 func TestDomainRegexp(t *testing.T) {
 	t.Parallel()
-	tests := []struct {
+	hostcases := []struct {
 		input string
 		match bool
 	}{
@@ -162,7 +162,7 @@ func TestDomainRegexp(t *testing.T) {
 		},
 	}
 	r := regexp.MustCompile(`^` + DomainRegexp.String() + `$`)
-	for _, tc := range tests {
+	for _, tc := range hostcases {
 		tc := tc
 		t.Run(tc.input, func(t *testing.T) {
 			t.Parallel()
@@ -181,7 +181,7 @@ func TestFullNameRegexp(t *testing.T) {
 			anchoredNameRegexp, anchoredNameRegexp.NumSubexp())
 	}
 
-	tests := []regexpMatch{
+	testcases := []regexpMatch{
 		{
 			input: "",
 			match: false,
@@ -465,7 +465,7 @@ func TestFullNameRegexp(t *testing.T) {
 			match: false,
 		},
 	}
-	for _, tc := range tests {
+	for _, tc := range testcases {
 		tc := tc
 		t.Run(tc.input, func(t *testing.T) {
 			t.Parallel()
@@ -481,7 +481,7 @@ func TestReferenceRegexp(t *testing.T) {
 			ReferenceRegexp, ReferenceRegexp.NumSubexp())
 	}
 
-	tests := []regexpMatch{
+	testcases := []regexpMatch{
 		{
 			input: "registry.com:8080/myapp:tag",
 			match: true,
@@ -540,7 +540,7 @@ func TestReferenceRegexp(t *testing.T) {
 		},
 	}
 
-	for _, tc := range tests {
+	for _, tc := range testcases {
 		tc := tc
 		t.Run(tc.input, func(t *testing.T) {
 			t.Parallel()
@@ -551,7 +551,7 @@ func TestReferenceRegexp(t *testing.T) {
 
 func TestIdentifierRegexp(t *testing.T) {
 	t.Parallel()
-	tests := []struct {
+	fullCases := []struct {
 		input string
 		match bool
 	}{
@@ -576,7 +576,7 @@ func TestIdentifierRegexp(t *testing.T) {
 			match: false,
 		},
 	}
-	for _, tc := range tests {
+	for _, tc := range fullCases {
 		tc := tc
 		t.Run(tc.input, func(t *testing.T) {
 			t.Parallel()
diff --git a/registry/api/errcode/errors_test.go b/registry/api/errcode/errors_test.go
index 105d9f7c..89ee9f3d 100644
--- a/registry/api/errcode/errors_test.go
+++ b/registry/api/errcode/errors_test.go
@@ -34,63 +34,57 @@ var ErrorCodeTest3 = Register("test.errors", ErrorDescriptor{
 // TestErrorCodes ensures that error code format, mappings and
 // marshaling/unmarshaling. round trips are stable.
 func TestErrorCodes(t *testing.T) {
-	t.Parallel()
 	if len(errorCodeToDescriptors) == 0 {
 		t.Fatal("errors aren't loaded!")
 	}
 
-	for ec := range errorCodeToDescriptors {
-		ec := ec
-		t.Run(ec.String(), func(t *testing.T) {
-			t.Parallel()
-			desc := errorCodeToDescriptors[ec]
-			if ec != desc.Code {
-				t.Fatalf("error code in descriptor isn't correct, %q != %q", ec, desc.Code)
-			}
-
-			if idToDescriptors[desc.Value].Code != ec {
-				t.Fatalf("error code in idToDesc isn't correct, %q != %q", idToDescriptors[desc.Value].Code, ec)
-			}
-
-			if ec.Message() != desc.Message {
-				t.Fatalf("ec.Message doesn't match desc.Message: %q != %q", ec.Message(), desc.Message)
-			}
-
-			// Test (de)serializing the ErrorCode
-			p, err := json.Marshal(ec)
-			if err != nil {
-				t.Fatalf("couldn't marshal ec %v: %v", ec, err)
-			}
-
-			if len(p) <= 0 {
-				t.Fatalf("expected content in marshaled before for error code %v", ec)
-			}
-
-			// First, unmarshal to interface and ensure we have a string.
-			var ecUnspecified interface{}
-			if err := json.Unmarshal(p, &ecUnspecified); err != nil {
-				t.Fatalf("error unmarshaling error code %v: %v", ec, err)
-			}
-
-			if _, ok := ecUnspecified.(string); !ok {
-				t.Fatalf("expected a string for error code %v on unmarshal got a %T", ec, ecUnspecified)
-			}
-
-			// Now, unmarshal with the error code type and ensure they are equal
-			var ecUnmarshaled ErrorCode
-			if err := json.Unmarshal(p, &ecUnmarshaled); err != nil {
-				t.Fatalf("error unmarshaling error code %v: %v", ec, err)
-			}
-
-			if ecUnmarshaled != ec {
-				t.Fatalf("unexpected error code during error code marshal/unmarshal: %v != %v", ecUnmarshaled, ec)
-			}
-
-			expectedErrorString := strings.ToLower(strings.Replace(ec.Descriptor().Value, "_", " ", -1))
-			if ec.Error() != expectedErrorString {
-				t.Fatalf("unexpected return from %v.Error(): %q != %q", ec, ec.Error(), expectedErrorString)
-			}
-		})
+	for ec, desc := range errorCodeToDescriptors {
+		if ec != desc.Code {
+			t.Fatalf("error code in descriptor isn't correct, %q != %q", ec, desc.Code)
+		}
+
+		if idToDescriptors[desc.Value].Code != ec {
+			t.Fatalf("error code in idToDesc isn't correct, %q != %q", idToDescriptors[desc.Value].Code, ec)
+		}
+
+		if ec.Message() != desc.Message {
+			t.Fatalf("ec.Message doesn't mtach desc.Message: %q != %q", ec.Message(), desc.Message)
+		}
+
+		// Test (de)serializing the ErrorCode
+		p, err := json.Marshal(ec)
+		if err != nil {
+			t.Fatalf("couldn't marshal ec %v: %v", ec, err)
+		}
+
+		if len(p) <= 0 {
+			t.Fatalf("expected content in marshaled before for error code %v", ec)
+		}
+
+		// First, unmarshal to interface and ensure we have a string.
+		var ecUnspecified interface{}
+		if err := json.Unmarshal(p, &ecUnspecified); err != nil {
+			t.Fatalf("error unmarshaling error code %v: %v", ec, err)
+		}
+
+		if _, ok := ecUnspecified.(string); !ok {
+			t.Fatalf("expected a string for error code %v on unmarshal got a %T", ec, ecUnspecified)
+		}
+
+		// Now, unmarshal with the error code type and ensure they are equal
+		var ecUnmarshaled ErrorCode
+		if err := json.Unmarshal(p, &ecUnmarshaled); err != nil {
+			t.Fatalf("error unmarshaling error code %v: %v", ec, err)
+		}
+
+		if ecUnmarshaled != ec {
+			t.Fatalf("unexpected error code during error code marshal/unmarshal: %v != %v", ecUnmarshaled, ec)
+		}
+
+		expectedErrorString := strings.ToLower(strings.Replace(ec.Descriptor().Value, "_", " ", -1))
+		if ec.Error() != expectedErrorString {
+			t.Fatalf("unexpected return from %v.Error(): %q != %q", ec, ec.Error(), expectedErrorString)
+		}
 	}
 }
 
diff --git a/registry/api/v2/routes_test.go b/registry/api/v2/routes_test.go
index bdd0ef48..b91fc48f 100644
--- a/registry/api/v2/routes_test.go
+++ b/registry/api/v2/routes_test.go
@@ -29,8 +29,7 @@ type routeTestCase struct {
 //
 // This may go away as the application structure comes together.
 func TestRouter(t *testing.T) {
-	t.Parallel()
-	tests := []routeTestCase{
+	testCases := []routeTestCase{
 		{
 			RouteName:  RouteNameBase,
 			RequestURI: "/v2/",
@@ -173,13 +172,12 @@ func TestRouter(t *testing.T) {
 		},
 	}
 
-	checkTestRouter(t, tests, "", true)
-	checkTestRouter(t, tests, "/prefix/", true)
+	checkTestRouter(t, testCases, "", true)
+	checkTestRouter(t, testCases, "/prefix/", true)
 }
 
 func TestRouterWithPathTraversals(t *testing.T) {
-	t.Parallel()
-	tests := []routeTestCase{
+	testCases := []routeTestCase{
 		{
 			RouteName:   RouteNameBlobUploadChunk,
 			RequestURI:  "/v2/foo/../../blobs/uploads/D95306FA-FAD3-4E36-8D41-CF1C93EF8286",
@@ -196,13 +194,12 @@ func TestRouterWithPathTraversals(t *testing.T) {
 			},
 		},
 	}
-	checkTestRouter(t, tests, "", false)
+	checkTestRouter(t, testCases, "", false)
 }
 
 func TestRouterWithBadCharacters(t *testing.T) {
-	t.Parallel()
 	if testing.Short() {
-		tests := []routeTestCase{
+		testCases := []routeTestCase{
 			{
 				RouteName:  RouteNameBlobUploadChunk,
 				RequestURI: "/v2/foo/blobs/uploads/不95306FA-FAD3-4E36-8D41-CF1C93EF8286",
@@ -215,26 +212,26 @@ func TestRouterWithBadCharacters(t *testing.T) {
 				StatusCode: http.StatusNotFound,
 			},
 		}
-		checkTestRouter(t, tests, "", true)
+		checkTestRouter(t, testCases, "", true)
 	} else {
 		// in the long version we're going to fuzz the router
 		// with random UTF8 characters not in the 128 bit ASCII range.
 		// These are not valid characters for the router and we expect
 		// 404s on every test.
 		rand.Seed(time.Now().UTC().UnixNano())
-		tests := make([]routeTestCase, 1000)
-		for idx := range tests {
-			tests[idx] = routeTestCase{
+		testCases := make([]routeTestCase, 1000)
+		for idx := range testCases {
+			testCases[idx] = routeTestCase{
 				RouteName:  RouteNameTags,
 				RequestURI: fmt.Sprintf("/v2/%v/%v/tags/list", randomString(10), randomString(10)),
 				StatusCode: http.StatusNotFound,
 			}
 		}
-		checkTestRouter(t, tests, "", true)
+		checkTestRouter(t, testCases, "", true)
 	}
 }
 
-func checkTestRouter(t *testing.T, tests []routeTestCase, prefix string, deeplyEqual bool) {
+func checkTestRouter(t *testing.T, testCases []routeTestCase, prefix string, deeplyEqual bool) {
 	router := RouterWithPrefix(prefix)
 
 	testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -255,73 +252,68 @@ func checkTestRouter(t *testing.T, tests []routeTestCase, prefix string, deeplyE
 	// Startup test server
 	server := httptest.NewServer(router)
 
-	for _, tc := range tests {
-		tc := tc
-		requestURI := strings.TrimSuffix(prefix, "/") + tc.RequestURI
-		t.Run("("+tc.RouteName+")"+requestURI, func(t *testing.T) {
-			t.Parallel()
-			tc.RequestURI = requestURI
-			// Register the endpoint
-			route := router.GetRoute(tc.RouteName)
-			if route == nil {
-				t.Fatalf("route for name %q not found", tc.RouteName)
-			}
+	for _, testcase := range testCases {
+		testcase.RequestURI = strings.TrimSuffix(prefix, "/") + testcase.RequestURI
+		// Register the endpoint
+		route := router.GetRoute(testcase.RouteName)
+		if route == nil {
+			t.Fatalf("route for name %q not found", testcase.RouteName)
+		}
 
-			route.Handler(testHandler)
+		route.Handler(testHandler)
 
-			u := server.URL + tc.RequestURI
+		u := server.URL + testcase.RequestURI
 
-			resp, err := http.Get(u)
-			if err != nil {
-				t.Fatalf("error issuing get request: %v", err)
-			}
+		resp, err := http.Get(u)
+		if err != nil {
+			t.Fatalf("error issuing get request: %v", err)
+		}
 
-			if tc.StatusCode == 0 {
-				// Override default, zero-value
-				tc.StatusCode = http.StatusOK
-			}
-			if tc.ExpectedURI == "" {
-				// Override default, zero-value
-				tc.ExpectedURI = tc.RequestURI
-			}
+		if testcase.StatusCode == 0 {
+			// Override default, zero-value
+			testcase.StatusCode = http.StatusOK
+		}
+		if testcase.ExpectedURI == "" {
+			// Override default, zero-value
+			testcase.ExpectedURI = testcase.RequestURI
+		}
 
-			if resp.StatusCode != tc.StatusCode {
-				t.Fatalf("unexpected status for %s: %v %v", u, resp.Status, resp.StatusCode)
-			}
+		if resp.StatusCode != testcase.StatusCode {
+			t.Fatalf("unexpected status for %s: %v %v", u, resp.Status, resp.StatusCode)
+		}
 
-			if tc.StatusCode != http.StatusOK {
-				resp.Body.Close()
-				// We don't care about json response.
-				return
-			}
+		if testcase.StatusCode != http.StatusOK {
+			resp.Body.Close()
+			// We don't care about json response.
+			continue
+		}
 
-			dec := json.NewDecoder(resp.Body)
+		dec := json.NewDecoder(resp.Body)
 
-			var actualRouteInfo routeTestCase
-			if err := dec.Decode(&actualRouteInfo); err != nil {
-				t.Fatalf("error reading json response: %v", err)
-			}
-			// Needs to be set out of band
-			actualRouteInfo.StatusCode = resp.StatusCode
+		var actualRouteInfo routeTestCase
+		if err := dec.Decode(&actualRouteInfo); err != nil {
+			t.Fatalf("error reading json response: %v", err)
+		}
+		// Needs to be set out of band
+		actualRouteInfo.StatusCode = resp.StatusCode
 
-			if actualRouteInfo.RequestURI != tc.ExpectedURI {
-				t.Fatalf("URI %v incorrectly parsed, expected %v", actualRouteInfo.RequestURI, tc.ExpectedURI)
-			}
+		if actualRouteInfo.RequestURI != testcase.ExpectedURI {
+			t.Fatalf("URI %v incorrectly parsed, expected %v", actualRouteInfo.RequestURI, testcase.ExpectedURI)
+		}
 
-			if actualRouteInfo.RouteName != tc.RouteName {
-				t.Fatalf("incorrect route %q matched, expected %q", actualRouteInfo.RouteName, tc.RouteName)
-			}
+		if actualRouteInfo.RouteName != testcase.RouteName {
+			t.Fatalf("incorrect route %q matched, expected %q", actualRouteInfo.RouteName, testcase.RouteName)
+		}
 
-			// when testing deep equality, the actualRouteInfo has an empty ExpectedURI, we don't want
-			// that to make the comparison fail. We're otherwise done with the testcase so empty the
-			// testcase.ExpectedURI
-			tc.ExpectedURI = ""
-			if deeplyEqual && !reflect.DeepEqual(actualRouteInfo, tc) {
-				t.Fatalf("actual does not equal expected: %#v != %#v", actualRouteInfo, tc)
-			}
+		// when testing deep equality, the actualRouteInfo has an empty ExpectedURI, we don't want
+		// that to make the comparison fail. We're otherwise done with the testcase so empty the
+		// testcase.ExpectedURI
+		testcase.ExpectedURI = ""
+		if deeplyEqual && !reflect.DeepEqual(actualRouteInfo, testcase) {
+			t.Fatalf("actual does not equal expected: %#v != %#v", actualRouteInfo, testcase)
+		}
 
-			resp.Body.Close()
-		})
+		resp.Body.Close()
 	}
 }
 
diff --git a/registry/api/v2/urls_test.go b/registry/api/v2/urls_test.go
index 0ccf3518..66fb4fd0 100644
--- a/registry/api/v2/urls_test.go
+++ b/registry/api/v2/urls_test.go
@@ -138,23 +138,23 @@ func TestURLBuilder(t *testing.T) {
 				t.Fatalf("unexpected error creating urlbuilder: %v", err)
 			}
 
-			for _, tc := range makeURLBuilderTestCases(urlBuilder) {
-				buildURL, err := tc.build()
-				expectedErr := tc.expectedErr
+			for _, testCase := range makeURLBuilderTestCases(urlBuilder) {
+				url, err := testCase.build()
+				expectedErr := testCase.expectedErr
 				if !reflect.DeepEqual(expectedErr, err) {
-					t.Fatalf("%s: Expecting %v but got error %v", tc.description, expectedErr, err)
+					t.Fatalf("%s: Expecting %v but got error %v", testCase.description, expectedErr, err)
 				}
 				if expectedErr != nil {
 					continue
 				}
 
-				expectedURL := tc.expectedPath
+				expectedURL := testCase.expectedPath
 				if !relative {
 					expectedURL = root + expectedURL
 				}
 
-				if buildURL != expectedURL {
-					t.Fatalf("%s: %q != %q", tc.description, buildURL, expectedURL)
+				if url != expectedURL {
+					t.Fatalf("%s: %q != %q", testCase.description, url, expectedURL)
 				}
 			}
 		}
@@ -178,22 +178,22 @@ func TestURLBuilderWithPrefix(t *testing.T) {
 				t.Fatalf("unexpected error creating urlbuilder: %v", err)
 			}
 
-			for _, tc := range makeURLBuilderTestCases(urlBuilder) {
-				buildURL, err := tc.build()
-				expectedErr := tc.expectedErr
+			for _, testCase := range makeURLBuilderTestCases(urlBuilder) {
+				url, err := testCase.build()
+				expectedErr := testCase.expectedErr
 				if !reflect.DeepEqual(expectedErr, err) {
-					t.Fatalf("%s: Expecting %v but got error %v", tc.description, expectedErr, err)
+					t.Fatalf("%s: Expecting %v but got error %v", testCase.description, expectedErr, err)
 				}
 				if expectedErr != nil {
 					continue
 				}
 
-				expectedURL := tc.expectedPath
+				expectedURL := testCase.expectedPath
 				if !relative {
 					expectedURL = root[0:len(root)-1] + expectedURL
 				}
-				if buildURL != expectedURL {
-					t.Fatalf("%s: %q != %q", tc.description, buildURL, expectedURL)
+				if url != expectedURL {
+					t.Fatalf("%s: %q != %q", testCase.description, url, expectedURL)
 				}
 			}
 		}
@@ -424,23 +424,23 @@ func TestBuilderFromRequest(t *testing.T) {
 				builder = NewURLBuilderFromRequest(tr.request, relative)
 			}
 
-			for _, tc := range makeURLBuilderTestCases(builder) {
-				buildURL, err := tc.build()
-				expectedErr := tc.expectedErr
+			for _, testCase := range makeURLBuilderTestCases(builder) {
+				buildURL, err := testCase.build()
+				expectedErr := testCase.expectedErr
 				if !reflect.DeepEqual(expectedErr, err) {
-					t.Fatalf("%s: Expecting %v but got error %v", tc.description, expectedErr, err)
+					t.Fatalf("%s: Expecting %v but got error %v", testCase.description, expectedErr, err)
 				}
 				if expectedErr != nil {
 					continue
 				}
 
-				expectedURL := tc.expectedPath
+				expectedURL := testCase.expectedPath
 				if !relative {
 					expectedURL = tr.base + expectedURL
 				}
 
 				if buildURL != expectedURL {
-					t.Errorf("[relative=%t, request=%q, case=%q]: %q != %q", relative, tr.name, tc.description, buildURL, expectedURL)
+					t.Errorf("[relative=%t, request=%q, case=%q]: %q != %q", relative, tr.name, testCase.description, buildURL, expectedURL)
 				}
 			}
 		}
@@ -497,11 +497,11 @@ func TestBuilderFromRequestWithPrefix(t *testing.T) {
 			builder = NewURLBuilderFromRequest(tr.request, false)
 		}
 
-		for _, tc := range makeURLBuilderTestCases(builder) {
-			buildURL, err := tc.build()
-			expectedErr := tc.expectedErr
+		for _, testCase := range makeURLBuilderTestCases(builder) {
+			buildURL, err := testCase.build()
+			expectedErr := testCase.expectedErr
 			if !reflect.DeepEqual(expectedErr, err) {
-				t.Fatalf("%s: Expecting %v but got error %v", tc.description, expectedErr, err)
+				t.Fatalf("%s: Expecting %v but got error %v", testCase.description, expectedErr, err)
 			}
 			if expectedErr != nil {
 				continue
@@ -510,7 +510,7 @@ func TestBuilderFromRequestWithPrefix(t *testing.T) {
 			var expectedURL string
 			proto, ok := tr.request.Header["X-Forwarded-Proto"]
 			if !ok {
-				expectedURL = tc.expectedPath
+				expectedURL = testCase.expectedPath
 				if !relative {
 					expectedURL = tr.base[0:len(tr.base)-1] + expectedURL
 				}
@@ -520,7 +520,7 @@ func TestBuilderFromRequestWithPrefix(t *testing.T) {
 					t.Fatal(err)
 				}
 				urlBase.Scheme = proto[0]
-				expectedURL = tc.expectedPath
+				expectedURL = testCase.expectedPath
 				if !relative {
 					expectedURL = urlBase.String()[0:len(urlBase.String())-1] + expectedURL
 				}
@@ -528,7 +528,7 @@ func TestBuilderFromRequestWithPrefix(t *testing.T) {
 			}
 
 			if buildURL != expectedURL {
-				t.Fatalf("%s: %q != %q", tc.description, buildURL, expectedURL)
+				t.Fatalf("%s: %q != %q", testCase.description, buildURL, expectedURL)
 			}
 		}
 	}
diff --git a/registry/auth/token/token_test.go b/registry/auth/token/token_test.go
index 8d322ae1..2837ad33 100644
--- a/registry/auth/token/token_test.go
+++ b/registry/auth/token/token_test.go
@@ -526,7 +526,7 @@ func TestNewAccessControllerPemBlock(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if len(ac.(*accessController).rootCerts.Subjects()) != 2 { //nolint:staticcheck // FIXME(thaJeztah): ignore SA1019: ac.(*accessController).rootCerts.Subjects has been deprecated since Go 1.18: if s was returned by SystemCertPool, Subjects will not include the system roots. (staticcheck)
+	if len(ac.(*accessController).rootCerts.Subjects()) != 2 {
 		t.Fatal("accessController has the wrong number of certificates")
 	}
 }
diff --git a/registry/auth/token/types_test.go b/registry/auth/token/types_test.go
index f38dab81..5e547761 100644
--- a/registry/auth/token/types_test.go
+++ b/registry/auth/token/types_test.go
@@ -6,9 +6,8 @@ import (
 )
 
 func TestAudienceList_Unmarshal(t *testing.T) {
-	t.Parallel()
 	t.Run("OK", func(t *testing.T) {
-		tests := []struct {
+		testCases := []struct {
 			value    string
 			expected AudienceList
 		}{
@@ -26,24 +25,23 @@ func TestAudienceList_Unmarshal(t *testing.T) {
 			},
 		}
 
-		for _, tc := range tests {
-			tc := tc
+		for _, testCase := range testCases {
+			testCase := testCase
+
 			t.Run("", func(t *testing.T) {
-				t.Parallel()
 				var actual AudienceList
 
-				err := json.Unmarshal([]byte(tc.value), &actual)
+				err := json.Unmarshal([]byte(testCase.value), &actual)
 				if err != nil {
 					t.Fatal(err)
 				}
 
-				assertStringListEqual(t, tc.expected, actual)
+				assertStringListEqual(t, testCase.expected, actual)
 			})
 		}
 	})
 
 	t.Run("Error", func(t *testing.T) {
-		t.Parallel()
 		var actual AudienceList
 
 		err := json.Unmarshal([]byte("1234"), &actual)
@@ -81,5 +79,7 @@ func assertStringListEqual(t *testing.T, expected []string, actual []string) {
 		if v != actual[i] {
 			t.Errorf("expected %d. item to be %q, got %q", i, v, actual[i])
 		}
+
+		return
 	}
 }
diff --git a/registry/client/repository_test.go b/registry/client/repository_test.go
index 7681bf86..4e926de7 100644
--- a/registry/client/repository_test.go
+++ b/registry/client/repository_test.go
@@ -19,7 +19,7 @@ import (
 	"github.com/distribution/distribution/v3"
 	"github.com/distribution/distribution/v3/context"
 	"github.com/distribution/distribution/v3/manifest"
-	"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	"github.com/distribution/distribution/v3/manifest/schema1"
 	"github.com/distribution/distribution/v3/reference"
 	"github.com/distribution/distribution/v3/registry/api/errcode"
 	v2 "github.com/distribution/distribution/v3/registry/api/v2"
@@ -917,18 +917,18 @@ func TestBlobMount(t *testing.T) {
 	}
 }
 
-func newRandomSchemaV1Manifest(name reference.Named, tag string, blobCount int) (*schema1.SignedManifest, digest.Digest, []byte) { //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
-	blobs := make([]schema1.FSLayer, blobCount)   //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
-	history := make([]schema1.History, blobCount) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+func newRandomSchemaV1Manifest(name reference.Named, tag string, blobCount int) (*schema1.SignedManifest, digest.Digest, []byte) {
+	blobs := make([]schema1.FSLayer, blobCount)
+	history := make([]schema1.History, blobCount)
 
 	for i := 0; i < blobCount; i++ {
 		dgst, blob := newRandomBlob((i % 5) * 16)
 
-		blobs[i] = schema1.FSLayer{BlobSum: dgst}                                             //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
-		history[i] = schema1.History{V1Compatibility: fmt.Sprintf("{\"Hex\": \"%x\"}", blob)} //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+		blobs[i] = schema1.FSLayer{BlobSum: dgst}
+		history[i] = schema1.History{V1Compatibility: fmt.Sprintf("{\"Hex\": \"%x\"}", blob)}
 	}
 
-	m := schema1.Manifest{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	m := schema1.Manifest{
 		Name:         name.String(),
 		Tag:          tag,
 		Architecture: "x86",
@@ -944,7 +944,7 @@ func newRandomSchemaV1Manifest(name reference.Named, tag string, blobCount int)
 		panic(err)
 	}
 
-	sm, err := schema1.Sign(&m, pk) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	sm, err := schema1.Sign(&m, pk)
 	if err != nil {
 		panic(err)
 	}
@@ -970,7 +970,7 @@ func addTestManifestWithEtag(repo reference.Named, reference string, content []b
 			Headers: http.Header(map[string][]string{
 				"Content-Length": {"0"},
 				"Last-Modified":  {time.Now().Add(-1 * time.Second).Format(time.ANSIC)},
-				"Content-Type":   {schema1.MediaTypeSignedManifest}, //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+				"Content-Type":   {schema1.MediaTypeSignedManifest},
 			}),
 		}
 	} else {
@@ -980,7 +980,7 @@ func addTestManifestWithEtag(repo reference.Named, reference string, content []b
 			Headers: http.Header(map[string][]string{
 				"Content-Length": {fmt.Sprint(len(content))},
 				"Last-Modified":  {time.Now().Add(-1 * time.Second).Format(time.ANSIC)},
-				"Content-Type":   {schema1.MediaTypeSignedManifest}, //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+				"Content-Type":   {schema1.MediaTypeSignedManifest},
 			}),
 		}
 	}
@@ -988,9 +988,9 @@ func addTestManifestWithEtag(repo reference.Named, reference string, content []b
 }
 
 func contentDigestString(mediatype string, content []byte) string {
-	if mediatype == schema1.MediaTypeSignedManifest { //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	if mediatype == schema1.MediaTypeSignedManifest {
 		m, _, _ := distribution.UnmarshalManifest(mediatype, content)
-		content = m.(*schema1.SignedManifest).Canonical //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+		content = m.(*schema1.SignedManifest).Canonical
 	}
 	return digest.Canonical.FromBytes(content).String()
 }
@@ -1061,7 +1061,7 @@ func addTestManifestWithoutDigestHeader(repo reference.Named, reference string,
 	})
 }
 
-func checkEqualManifest(m1, m2 *schema1.SignedManifest) error { //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+func checkEqualManifest(m1, m2 *schema1.SignedManifest) error {
 	if m1.Name != m2.Name {
 		return fmt.Errorf("name does not match %q != %q", m1.Name, m2.Name)
 	}
@@ -1092,12 +1092,12 @@ func TestV1ManifestFetch(t *testing.T) {
 	repo, _ := reference.WithName("test.example.com/repo")
 	m1, dgst, _ := newRandomSchemaV1Manifest(repo, "latest", 6)
 	var m testutil.RequestResponseMap
-	_, pl, err := m1.Payload() //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	_, pl, err := m1.Payload()
 	if err != nil {
 		t.Fatal(err)
 	}
-	addTestManifest(repo, dgst.String(), schema1.MediaTypeSignedManifest, pl, &m) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
-	addTestManifest(repo, "latest", schema1.MediaTypeSignedManifest, pl, &m)      //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	addTestManifest(repo, dgst.String(), schema1.MediaTypeSignedManifest, pl, &m)
+	addTestManifest(repo, "latest", schema1.MediaTypeSignedManifest, pl, &m)
 	addTestManifest(repo, "badcontenttype", "text/html", pl, &m)
 
 	e, c := testServer(m)
@@ -1124,7 +1124,7 @@ func TestV1ManifestFetch(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	v1manifest, ok := manifest.(*schema1.SignedManifest) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	v1manifest, ok := manifest.(*schema1.SignedManifest)
 	if !ok {
 		t.Fatalf("Unexpected manifest type from Get: %T", manifest)
 	}
@@ -1138,7 +1138,7 @@ func TestV1ManifestFetch(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	v1manifest, ok = manifest.(*schema1.SignedManifest) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	v1manifest, ok = manifest.(*schema1.SignedManifest)
 	if !ok {
 		t.Fatalf("Unexpected manifest type from Get: %T", manifest)
 	}
@@ -1155,7 +1155,7 @@ func TestV1ManifestFetch(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	v1manifest, ok = manifest.(*schema1.SignedManifest) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	v1manifest, ok = manifest.(*schema1.SignedManifest)
 	if !ok {
 		t.Fatalf("Unexpected manifest type from Get: %T", manifest)
 	}
@@ -1298,7 +1298,7 @@ func TestManifestPut(t *testing.T) {
 	repo, _ := reference.WithName("test.example.com/repo/delete")
 	m1, dgst, _ := newRandomSchemaV1Manifest(repo, "other", 6)
 
-	_, payload, err := m1.Payload() //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	_, payload, err := m1.Payload()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1506,11 +1506,11 @@ func TestObtainsManifestForTagWithoutHeaders(t *testing.T) {
 
 	var m testutil.RequestResponseMap
 	m1, dgst, _ := newRandomSchemaV1Manifest(repo, "latest", 6)
-	_, pl, err := m1.Payload() //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	_, pl, err := m1.Payload()
 	if err != nil {
 		t.Fatal(err)
 	}
-	addTestManifestWithoutDigestHeader(repo, "1.0.0", schema1.MediaTypeSignedManifest, pl, &m) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	addTestManifestWithoutDigestHeader(repo, "1.0.0", schema1.MediaTypeSignedManifest, pl, &m)
 
 	e, c := testServer(m)
 	defer c()
diff --git a/registry/handlers/api_test.go b/registry/handlers/api_test.go
index 5fd1790c..dcbc1de6 100644
--- a/registry/handlers/api_test.go
+++ b/registry/handlers/api_test.go
@@ -23,14 +23,14 @@ import (
 	"github.com/distribution/distribution/v3/configuration"
 	"github.com/distribution/distribution/v3/manifest"
 	"github.com/distribution/distribution/v3/manifest/manifestlist"
-	"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	"github.com/distribution/distribution/v3/manifest/schema1"
 	"github.com/distribution/distribution/v3/manifest/schema2"
 	"github.com/distribution/distribution/v3/reference"
 	"github.com/distribution/distribution/v3/registry/api/errcode"
 	v2 "github.com/distribution/distribution/v3/registry/api/v2"
 	storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
 	"github.com/distribution/distribution/v3/registry/storage/driver/factory"
-	_ "github.com/distribution/distribution/v3/registry/storage/driver/inmemory"
+	_ "github.com/distribution/distribution/v3/registry/storage/driver/testdriver"
 	"github.com/distribution/distribution/v3/testutil"
 	"github.com/docker/libtrust"
 	"github.com/gorilla/handlers"
@@ -80,23 +80,22 @@ func TestCheckAPI(t *testing.T) {
 
 // TestCatalogAPI tests the /v2/_catalog endpoint
 func TestCatalogAPI(t *testing.T) {
+	chunkLen := 2
 	env := newTestEnv(t, false)
 	defer env.Shutdown()
 
-	maxEntries := env.config.Catalog.MaxEntries
-	allCatalog := []string{
-		"foo/aaaa", "foo/bbbb", "foo/cccc", "foo/dddd", "foo/eeee", "foo/ffff",
+	values := url.Values{
+		"last": []string{""},
+		"n":    []string{strconv.Itoa(chunkLen)},
 	}
 
-	chunkLen := maxEntries - 1
-
-	catalogURL, err := env.builder.BuildCatalogURL()
+	catalogURL, err := env.builder.BuildCatalogURL(values)
 	if err != nil {
 		t.Fatalf("unexpected error building catalog url: %v", err)
 	}
 
 	// -----------------------------------
-	// Case No. 1: Empty catalog
+	// try to get an empty catalog
 	resp, err := http.Get(catalogURL)
 	if err != nil {
 		t.Fatalf("unexpected error issuing request: %v", err)
@@ -114,23 +113,23 @@ func TestCatalogAPI(t *testing.T) {
 		t.Fatalf("error decoding fetched manifest: %v", err)
 	}
 
-	// No images pushed = no image returned
+	// we haven't pushed anything to the registry yet
 	if len(ctlg.Repositories) != 0 {
-		t.Fatalf("repositories returned unexpected entries (expected: %d, returned: %d)", 0, len(ctlg.Repositories))
+		t.Fatalf("repositories has unexpected values")
 	}
 
-	// No pagination should be returned
 	if resp.Header.Get("Link") != "" {
 		t.Fatalf("repositories has more data when none expected")
 	}
 
-	for _, image := range allCatalog {
+	// -----------------------------------
+	// push something to the registry and try again
+	images := []string{"foo/aaaa", "foo/bbbb", "foo/cccc"}
+
+	for _, image := range images {
 		createRepository(env, t, image, "sometag")
 	}
 
-	// -----------------------------------
-	// Case No. 2: Catalog populated & n is not provided nil (n internally will be min(100, maxEntries))
-
 	resp, err = http.Get(catalogURL)
 	if err != nil {
 		t.Fatalf("unexpected error issuing request: %v", err)
@@ -144,61 +143,27 @@ func TestCatalogAPI(t *testing.T) {
 		t.Fatalf("error decoding fetched manifest: %v", err)
 	}
 
-	// it must match max entries
-	if len(ctlg.Repositories) != maxEntries {
-		t.Fatalf("repositories returned unexpected entries (expected: %d, returned: %d)", maxEntries, len(ctlg.Repositories))
+	if len(ctlg.Repositories) != chunkLen {
+		t.Fatalf("repositories has unexpected values")
 	}
 
-	// it must return the first maxEntries entries from the catalog
-	for _, image := range allCatalog[:maxEntries] {
+	for _, image := range images[:chunkLen] {
 		if !contains(ctlg.Repositories, image) {
 			t.Fatalf("didn't find our repository '%s' in the catalog", image)
 		}
 	}
 
-	// fail if there's no pagination
 	link := resp.Header.Get("Link")
 	if link == "" {
 		t.Fatalf("repositories has less data than expected")
 	}
-	// -----------------------------------
-	// Case No. 2.1: Second page (n internally will be min(100, maxEntries))
-
-	// build pagination link
-	values := checkLink(t, link, maxEntries, ctlg.Repositories[len(ctlg.Repositories)-1])
-
-	catalogURL, err = env.builder.BuildCatalogURL(values)
-	if err != nil {
-		t.Fatalf("unexpected error building catalog url: %v", err)
-	}
-
-	resp, err = http.Get(catalogURL)
-	if err != nil {
-		t.Fatalf("unexpected error issuing request: %v", err)
-	}
-	defer resp.Body.Close()
-
-	checkResponse(t, "issuing catalog api check", resp, http.StatusOK)
-
-	dec = json.NewDecoder(resp.Body)
-	if err = dec.Decode(&ctlg); err != nil {
-		t.Fatalf("error decoding fetched manifest: %v", err)
-	}
 
-	expectedRemainder := len(allCatalog) - maxEntries
-
-	if len(ctlg.Repositories) != expectedRemainder {
-		t.Fatalf("repositories returned unexpected entries (expected: %d, returned: %d)", expectedRemainder, len(ctlg.Repositories))
-	}
+	newValues := checkLink(t, link, chunkLen, ctlg.Repositories[len(ctlg.Repositories)-1])
 
 	// -----------------------------------
-	// Case No. 3: request n = maxentries
-	values = url.Values{
-		"last": []string{""},
-		"n":    []string{strconv.Itoa(maxEntries)},
-	}
+	// get the last chunk of data
 
-	catalogURL, err = env.builder.BuildCatalogURL(values)
+	catalogURL, err = env.builder.BuildCatalogURL(newValues)
 	if err != nil {
 		t.Fatalf("unexpected error building catalog url: %v", err)
 	}
@@ -216,236 +181,18 @@ func TestCatalogAPI(t *testing.T) {
 		t.Fatalf("error decoding fetched manifest: %v", err)
 	}
 
-	if len(ctlg.Repositories) != maxEntries {
-		t.Fatalf("repositories returned unexpected entries (expected: %d, returned: %d)", maxEntries, len(ctlg.Repositories))
+	if len(ctlg.Repositories) != 1 {
+		t.Fatalf("repositories has unexpected values")
 	}
 
-	// fail if there's no pagination
-	link = resp.Header.Get("Link")
-	if link == "" {
-		t.Fatalf("repositories has less data than expected")
+	lastImage := images[len(images)-1]
+	if !contains(ctlg.Repositories, lastImage) {
+		t.Fatalf("didn't find our repository '%s' in the catalog", lastImage)
 	}
 
-	// -----------------------------------
-	// Case No. 3.1: Second (last) page
-
-	// build pagination link
-	values = checkLink(t, link, maxEntries, ctlg.Repositories[len(ctlg.Repositories)-1])
-
-	catalogURL, err = env.builder.BuildCatalogURL(values)
-	if err != nil {
-		t.Fatalf("unexpected error building catalog url: %v", err)
-	}
-
-	resp, err = http.Get(catalogURL)
-	if err != nil {
-		t.Fatalf("unexpected error issuing request: %v", err)
-	}
-	defer resp.Body.Close()
-
-	checkResponse(t, "issuing catalog api check", resp, http.StatusOK)
-
-	dec = json.NewDecoder(resp.Body)
-	if err = dec.Decode(&ctlg); err != nil {
-		t.Fatalf("error decoding fetched manifest: %v", err)
-	}
-
-	expectedRemainder = len(allCatalog) - maxEntries
-
-	if len(ctlg.Repositories) != expectedRemainder {
-		t.Fatalf("repositories returned unexpected entries (expected: %d, returned: %d)", expectedRemainder, len(ctlg.Repositories))
-	}
-
-	// -----------------------------------
-	// Case No. 4: request n < maxentries
-
-	values = url.Values{
-		"n": []string{strconv.Itoa(chunkLen)},
-	}
-
-	catalogURL, err = env.builder.BuildCatalogURL(values)
-	if err != nil {
-		t.Fatalf("unexpected error building catalog url: %v", err)
-	}
-
-	resp, err = http.Get(catalogURL)
-	if err != nil {
-		t.Fatalf("unexpected error issuing request: %v", err)
-	}
-	defer resp.Body.Close()
-
-	checkResponse(t, "issuing catalog api check", resp, http.StatusOK)
-
-	dec = json.NewDecoder(resp.Body)
-	if err = dec.Decode(&ctlg); err != nil {
-		t.Fatalf("error decoding fetched manifest: %v", err)
-	}
-
-	// returns the requested amount
-	if len(ctlg.Repositories) != chunkLen {
-		t.Fatalf("repositories returned unexpected entries (expected: %d, returned: %d)", expectedRemainder, len(ctlg.Repositories))
-	}
-
-	// fail if there's no pagination
 	link = resp.Header.Get("Link")
-	if link == "" {
-		t.Fatalf("repositories has less data than expected")
-	}
-
-	// -----------------------------------
-	// Case No. 4.1: request n < maxentries (second page)
-
-	// build pagination link
-	values = checkLink(t, link, chunkLen, ctlg.Repositories[len(ctlg.Repositories)-1])
-
-	catalogURL, err = env.builder.BuildCatalogURL(values)
-	if err != nil {
-		t.Fatalf("unexpected error building catalog url: %v", err)
-	}
-
-	resp, err = http.Get(catalogURL)
-	if err != nil {
-		t.Fatalf("unexpected error issuing request: %v", err)
-	}
-	defer resp.Body.Close()
-
-	checkResponse(t, "issuing catalog api check", resp, http.StatusOK)
-
-	dec = json.NewDecoder(resp.Body)
-	if err = dec.Decode(&ctlg); err != nil {
-		t.Fatalf("error decoding fetched manifest: %v", err)
-	}
-
-	expectedRemainder = len(allCatalog) - chunkLen
-
-	if len(ctlg.Repositories) != expectedRemainder {
-		t.Fatalf("repositories returned unexpected entries (expected: %d, returned: %d)", expectedRemainder, len(ctlg.Repositories))
-	}
-
-	// -----------------------------------
-	// Case No. 5: request n > maxentries
-
-	values = url.Values{
-		"n": []string{strconv.Itoa(maxEntries + 10)},
-	}
-
-	catalogURL, err = env.builder.BuildCatalogURL(values)
-	if err != nil {
-		t.Fatalf("unexpected error building catalog url: %v", err)
-	}
-
-	resp, err = http.Get(catalogURL)
-	if err != nil {
-		t.Fatalf("unexpected error issuing request: %v", err)
-	}
-	defer resp.Body.Close()
-
-	checkResponse(t, "issuing catalog api check", resp, http.StatusBadRequest)
-	checkBodyHasErrorCodes(t, "invalid number of results requested", resp, v2.ErrorCodePaginationNumberInvalid)
-
-	// -----------------------------------
-	// Case No. 6: request n > maxentries but <= total catalog
-
-	values = url.Values{
-		"n": []string{strconv.Itoa(len(allCatalog))},
-	}
-
-	catalogURL, err = env.builder.BuildCatalogURL(values)
-	if err != nil {
-		t.Fatalf("unexpected error building catalog url: %v", err)
-	}
-
-	resp, err = http.Get(catalogURL)
-	if err != nil {
-		t.Fatalf("unexpected error issuing request: %v", err)
-	}
-	defer resp.Body.Close()
-
-	checkResponse(t, "issuing catalog api check", resp, http.StatusBadRequest)
-	checkBodyHasErrorCodes(t, "invalid number of results requested", resp, v2.ErrorCodePaginationNumberInvalid)
-
-	// -----------------------------------
-	// Case No. 7: n = 0
-	values = url.Values{
-		"n": []string{"0"},
-	}
-
-	catalogURL, err = env.builder.BuildCatalogURL(values)
-	if err != nil {
-		t.Fatalf("unexpected error building catalog url: %v", err)
-	}
-
-	resp, err = http.Get(catalogURL)
-	if err != nil {
-		t.Fatalf("unexpected error issuing request: %v", err)
-	}
-	defer resp.Body.Close()
-
-	checkResponse(t, "issuing catalog api check", resp, http.StatusOK)
-
-	dec = json.NewDecoder(resp.Body)
-	if err = dec.Decode(&ctlg); err != nil {
-		t.Fatalf("error decoding fetched manifest: %v", err)
-	}
-
-	// it must match max entries
-	if len(ctlg.Repositories) != 0 {
-		t.Fatalf("repositories returned unexpected entries (expected: %d, returned: %d)", 0, len(ctlg.Repositories))
-	}
-
-	// -----------------------------------
-	// Case No. 8: n = -1
-	values = url.Values{
-		"n": []string{"-1"},
-	}
-
-	catalogURL, err = env.builder.BuildCatalogURL(values)
-	if err != nil {
-		t.Fatalf("unexpected error building catalog url: %v", err)
-	}
-
-	resp, err = http.Get(catalogURL)
-	if err != nil {
-		t.Fatalf("unexpected error issuing request: %v", err)
-	}
-	defer resp.Body.Close()
-
-	checkResponse(t, "issuing catalog api check", resp, http.StatusBadRequest)
-	checkBodyHasErrorCodes(t, "invalid number of results requested", resp, v2.ErrorCodePaginationNumberInvalid)
-
-	// -----------------------------------
-	// Case No. 9: n = 5, max = 5, total catalog = 4
-	values = url.Values{
-		"n": []string{strconv.Itoa(maxEntries)},
-	}
-
-	envWithLessImages := newTestEnv(t, false)
-	for _, image := range allCatalog[0:(maxEntries - 1)] {
-		createRepository(envWithLessImages, t, image, "sometag")
-	}
-
-	catalogURL, err = envWithLessImages.builder.BuildCatalogURL(values)
-
-	if err != nil {
-		t.Fatalf("unexpected error building catalog url: %v", err)
-	}
-
-	resp, err = http.Get(catalogURL)
-	if err != nil {
-		t.Fatalf("unexpected error issuing request: %v", err)
-	}
-	defer resp.Body.Close()
-
-	checkResponse(t, "issuing catalog api check", resp, http.StatusOK)
-
-	dec = json.NewDecoder(resp.Body)
-	if err = dec.Decode(&ctlg); err != nil {
-		t.Fatalf("error decoding fetched manifest: %v", err)
-	}
-
-	// it must match max entries
-	if len(ctlg.Repositories) != maxEntries-1 {
-		t.Fatalf("repositories returned unexpected entries (expected: %d, returned: %d)", maxEntries-1, len(ctlg.Repositories))
+	if link != "" {
+		t.Fatalf("catalog has unexpected data")
 	}
 }
 
@@ -616,7 +363,7 @@ func checkLink(t *testing.T, urlStr string, numEntries int, last string) url.Val
 	urlValues := linkURL.Query()
 
 	if urlValues.Get("n") != strconv.Itoa(numEntries) {
-		t.Fatalf("Catalog link entry size is incorrect (expected: %v, returned: %v)", urlValues.Get("n"), strconv.Itoa(numEntries))
+		t.Fatalf("Catalog link entry size is incorrect")
 	}
 
 	if urlValues.Get("last") != last {
@@ -638,7 +385,7 @@ func contains(elems []string, e string) bool {
 func TestURLPrefix(t *testing.T) {
 	config := configuration.Configuration{
 		Storage: configuration.Storage{
-			"inmemory": configuration.Parameters{},
+			"testdriver": configuration.Parameters{},
 			"maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{
 				"enabled": false,
 			}},
@@ -721,7 +468,7 @@ func TestBlobDelete(t *testing.T) {
 func TestRelativeURL(t *testing.T) {
 	config := configuration.Configuration{
 		Storage: configuration.Storage{
-			"inmemory": configuration.Parameters{},
+			"testdriver": configuration.Parameters{},
 			"maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{
 				"enabled": false,
 			}},
@@ -1531,13 +1278,13 @@ func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Name
 
 	// --------------------------------
 	// Attempt to push unsigned manifest with missing layers
-	unsignedManifest := &schema1.Manifest{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	unsignedManifest := &schema1.Manifest{
 		Versioned: manifest.Versioned{
 			SchemaVersion: 1,
 		},
 		Name: imageName.Name(),
 		Tag:  tag,
-		FSLayers: []schema1.FSLayer{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+		FSLayers: []schema1.FSLayer{
 			{
 				BlobSum: "asdf",
 			},
@@ -1545,7 +1292,7 @@ func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Name
 				BlobSum: "qwer",
 			},
 		},
-		History: []schema1.History{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+		History: []schema1.History{
 			{
 				V1Compatibility: "",
 			},
@@ -1569,7 +1316,7 @@ func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Name
 	}
 
 	// sign the manifest and still get some interesting errors.
-	sm, err := schema1.Sign(unsignedManifest, env.pk) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	sm, err := schema1.Sign(unsignedManifest, env.pk)
 	if err != nil {
 		t.Fatalf("error signing manifest: %v", err)
 	}
@@ -1611,7 +1358,7 @@ func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Name
 
 	// -------------------
 	// Push the signed manifest with all layers pushed.
-	signedManifest, err := schema1.Sign(unsignedManifest, env.pk) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	signedManifest, err := schema1.Sign(unsignedManifest, env.pk)
 	if err != nil {
 		t.Fatalf("unexpected error signing manifest: %v", err)
 	}
@@ -1654,7 +1401,7 @@ func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Name
 		"ETag":                  []string{fmt.Sprintf(`"%s"`, dgst)},
 	})
 
-	var fetchedManifest schema1.SignedManifest //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	var fetchedManifest schema1.SignedManifest
 	dec := json.NewDecoder(resp.Body)
 
 	if err := dec.Decode(&fetchedManifest); err != nil {
@@ -1677,7 +1424,7 @@ func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Name
 		"ETag":                  []string{fmt.Sprintf(`"%s"`, dgst)},
 	})
 
-	var fetchedManifestByDigest schema1.SignedManifest //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	var fetchedManifestByDigest schema1.SignedManifest
 	dec = json.NewDecoder(resp.Body)
 	if err := dec.Decode(&fetchedManifestByDigest); err != nil {
 		t.Fatalf("error decoding fetched manifest: %v", err)
@@ -1688,7 +1435,7 @@ func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Name
 	}
 
 	// check signature was roundtripped
-	signatures, err := fetchedManifestByDigest.Signatures() //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	signatures, err := fetchedManifestByDigest.Signatures()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1698,7 +1445,7 @@ func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Name
 	}
 
 	// Re-sign, push and pull the same digest
-	sm2, err := schema1.Sign(&fetchedManifestByDigest.Manifest, env.pk) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	sm2, err := schema1.Sign(&fetchedManifestByDigest.Manifest, env.pk)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1706,7 +1453,7 @@ func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Name
 	// Re-push with a few different Content-Types. The official schema1
 	// content type should work, as should application/json with/without a
 	// charset.
-	resp = putManifest(t, "re-putting signed manifest", manifestDigestURL, schema1.MediaTypeSignedManifest, sm2) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	resp = putManifest(t, "re-putting signed manifest", manifestDigestURL, schema1.MediaTypeSignedManifest, sm2)
 	checkResponse(t, "re-putting signed manifest", resp, http.StatusCreated)
 	resp = putManifest(t, "re-putting signed manifest", manifestDigestURL, "application/json", sm2)
 	checkResponse(t, "re-putting signed manifest", resp, http.StatusCreated)
@@ -1729,7 +1476,7 @@ func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Name
 	}
 
 	// check only 1 signature is returned
-	signatures, err = fetchedManifestByDigest.Signatures() //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	signatures, err = fetchedManifestByDigest.Signatures()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1795,10 +1542,10 @@ func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Name
 
 	// Attempt to put a manifest with mismatching FSLayer and History array cardinalities
 
-	unsignedManifest.History = append(unsignedManifest.History, schema1.History{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	unsignedManifest.History = append(unsignedManifest.History, schema1.History{
 		V1Compatibility: "",
 	})
-	invalidSigned, err := schema1.Sign(unsignedManifest, env.pk) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	invalidSigned, err := schema1.Sign(unsignedManifest, env.pk)
 	if err != nil {
 		t.Fatalf("error signing manifest")
 	}
@@ -2116,12 +1863,12 @@ func testManifestAPISchema2(t *testing.T, env *testEnv, imageName reference.Name
 
 	checkResponse(t, "fetching uploaded manifest as schema1", resp, http.StatusOK)
 
-	m, desc, err := distribution.UnmarshalManifest(schema1.MediaTypeManifest, manifestBytes) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	m, desc, err := distribution.UnmarshalManifest(schema1.MediaTypeManifest, manifestBytes)
 	if err != nil {
 		t.Fatalf("unexpected error unmarshalling manifest: %v", err)
 	}
 
-	fetchedSchema1Manifest, ok := m.(*schema1.SignedManifest) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	fetchedSchema1Manifest, ok := m.(*schema1.SignedManifest)
 	if !ok {
 		t.Fatalf("expecting schema1 manifest")
 	}
@@ -2246,7 +1993,7 @@ func testManifestAPIManifestList(t *testing.T, env *testEnv, args manifestArgs)
 		t.Fatalf("Error constructing request: %s", err)
 	}
 	// multiple headers in mixed list format to ensure we parse correctly server-side
-	req.Header.Set("Accept", fmt.Sprintf(` %s ; q=0.8 , %s ; q=0.5 `, manifestlist.MediaTypeManifestList, schema1.MediaTypeSignedManifest)) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	req.Header.Set("Accept", fmt.Sprintf(` %s ; q=0.8 , %s ; q=0.5 `, manifestlist.MediaTypeManifestList, schema1.MediaTypeSignedManifest))
 	req.Header.Add("Accept", schema2.MediaTypeManifest)
 	resp, err = http.DefaultClient.Do(req)
 	if err != nil {
@@ -2350,12 +2097,12 @@ func testManifestAPIManifestList(t *testing.T, env *testEnv, args manifestArgs)
 
 	checkResponse(t, "fetching uploaded manifest list as schema1", resp, http.StatusOK)
 
-	m, desc, err := distribution.UnmarshalManifest(schema1.MediaTypeManifest, manifestBytes) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	m, desc, err := distribution.UnmarshalManifest(schema1.MediaTypeManifest, manifestBytes)
 	if err != nil {
 		t.Fatalf("unexpected error unmarshalling manifest: %v", err)
 	}
 
-	fetchedSchema1Manifest, ok := m.(*schema1.SignedManifest) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	fetchedSchema1Manifest, ok := m.(*schema1.SignedManifest)
 	if !ok {
 		t.Fatalf("expecting schema1 manifest")
 	}
@@ -2543,8 +2290,8 @@ func newTestEnvMirror(t *testing.T, deleteEnabled bool) *testEnv {
 	upstreamEnv := newTestEnv(t, deleteEnabled)
 	config := configuration.Configuration{
 		Storage: configuration.Storage{
-			"inmemory": configuration.Parameters{},
-			"delete":   configuration.Parameters{"enabled": deleteEnabled},
+			"testdriver": configuration.Parameters{},
+			"delete":     configuration.Parameters{"enabled": deleteEnabled},
 			"maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{
 				"enabled": false,
 			}},
@@ -2552,11 +2299,8 @@ func newTestEnvMirror(t *testing.T, deleteEnabled bool) *testEnv {
 		Proxy: configuration.Proxy{
 			RemoteURL: upstreamEnv.server.URL,
 		},
-		Catalog: configuration.Catalog{
-			MaxEntries: 5,
-		},
 	}
-	config.Compatibility.Schema1.Enabled = true //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	config.Compatibility.Schema1.Enabled = true
 
 	return newTestEnvWithConfig(t, &config)
 }
@@ -2564,18 +2308,15 @@ func newTestEnvMirror(t *testing.T, deleteEnabled bool) *testEnv {
 func newTestEnv(t *testing.T, deleteEnabled bool) *testEnv {
 	config := configuration.Configuration{
 		Storage: configuration.Storage{
-			"inmemory": configuration.Parameters{},
-			"delete":   configuration.Parameters{"enabled": deleteEnabled},
+			"testdriver": configuration.Parameters{},
+			"delete":     configuration.Parameters{"enabled": deleteEnabled},
 			"maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{
 				"enabled": false,
 			}},
 		},
-		Catalog: configuration.Catalog{
-			MaxEntries: 5,
-		},
 	}
 
-	config.Compatibility.Schema1.Enabled = true //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	config.Compatibility.Schema1.Enabled = true
 	config.HTTP.Headers = headerConfig
 
 	return newTestEnvWithConfig(t, &config)
@@ -2615,8 +2356,8 @@ func putManifest(t *testing.T, msg, url, contentType string, v interface{}) *htt
 	var body []byte
 
 	switch m := v.(type) {
-	case *schema1.SignedManifest: //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
-		_, pl, err := m.Payload() //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	case *schema1.SignedManifest:
+		_, pl, err := m.Payload()
 		if err != nil {
 			t.Fatalf("error getting payload: %v", err)
 		}
@@ -2853,6 +2594,7 @@ func checkResponse(t *testing.T, msg string, resp *http.Response, expectedStatus
 	if resp.StatusCode != expectedStatus {
 		t.Logf("unexpected status %s: %v != %v", msg, resp.StatusCode, expectedStatus)
 		maybeDumpResponse(t, resp)
+
 		t.FailNow()
 	}
 
@@ -2968,18 +2710,18 @@ func createRepository(env *testEnv, t *testing.T, imageName string, tag string)
 		t.Fatalf("unable to parse reference: %v", err)
 	}
 
-	unsignedManifest := &schema1.Manifest{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	unsignedManifest := &schema1.Manifest{
 		Versioned: manifest.Versioned{
 			SchemaVersion: 1,
 		},
 		Name: imageName,
 		Tag:  tag,
-		FSLayers: []schema1.FSLayer{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+		FSLayers: []schema1.FSLayer{
 			{
 				BlobSum: "asdf",
 			},
 		},
-		History: []schema1.History{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+		History: []schema1.History{
 			{
 				V1Compatibility: "",
 			},
@@ -3001,7 +2743,7 @@ func createRepository(env *testEnv, t *testing.T, imageName string, tag string)
 		pushLayer(t, env.builder, imageNameRef, dgst, uploadURLBase, rs)
 	}
 
-	signedManifest, err := schema1.Sign(unsignedManifest, env.pk) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	signedManifest, err := schema1.Sign(unsignedManifest, env.pk)
 	if err != nil {
 		t.Fatalf("unexpected error signing manifest: %v", err)
 	}
@@ -3042,17 +2784,17 @@ func TestRegistryAsCacheMutationAPIs(t *testing.T) {
 	}
 
 	// Manifest upload
-	m := &schema1.Manifest{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	m := &schema1.Manifest{
 		Versioned: manifest.Versioned{
 			SchemaVersion: 1,
 		},
 		Name:     imageName.Name(),
 		Tag:      tag,
-		FSLayers: []schema1.FSLayer{}, //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
-		History:  []schema1.History{}, //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+		FSLayers: []schema1.FSLayer{},
+		History:  []schema1.History{},
 	}
 
-	sm, err := schema1.Sign(m, env.pk) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	sm, err := schema1.Sign(m, env.pk)
 	if err != nil {
 		t.Fatalf("error signing manifest: %v", err)
 	}
@@ -3088,13 +2830,13 @@ func TestRegistryAsCacheMutationAPIs(t *testing.T) {
 func TestProxyManifestGetByTag(t *testing.T) {
 	truthConfig := configuration.Configuration{
 		Storage: configuration.Storage{
-			"inmemory": configuration.Parameters{},
+			"testdriver": configuration.Parameters{},
 			"maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{
 				"enabled": false,
 			}},
 		},
 	}
-	truthConfig.Compatibility.Schema1.Enabled = true //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	truthConfig.Compatibility.Schema1.Enabled = true
 	truthConfig.HTTP.Headers = headerConfig
 
 	imageName, _ := reference.WithName("foo/bar")
@@ -3107,13 +2849,13 @@ func TestProxyManifestGetByTag(t *testing.T) {
 
 	proxyConfig := configuration.Configuration{
 		Storage: configuration.Storage{
-			"inmemory": configuration.Parameters{},
+			"testdriver": configuration.Parameters{},
 		},
 		Proxy: configuration.Proxy{
 			RemoteURL: truthEnv.server.URL,
 		},
 	}
-	proxyConfig.Compatibility.Schema1.Enabled = true //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	proxyConfig.Compatibility.Schema1.Enabled = true
 	proxyConfig.HTTP.Headers = headerConfig
 
 	proxyEnv := newTestEnvWithConfig(t, &proxyConfig)
diff --git a/registry/handlers/app_test.go b/registry/handlers/app_test.go
index 408d76b9..09a5d7e8 100644
--- a/registry/handlers/app_test.go
+++ b/registry/handlers/app_test.go
@@ -16,7 +16,7 @@ import (
 	_ "github.com/distribution/distribution/v3/registry/auth/silly"
 	"github.com/distribution/distribution/v3/registry/storage"
 	memorycache "github.com/distribution/distribution/v3/registry/storage/cache/memory"
-	"github.com/distribution/distribution/v3/registry/storage/driver/inmemory"
+	"github.com/distribution/distribution/v3/registry/storage/driver/testdriver"
 )
 
 // TestAppDispatcher builds an application with a test dispatcher and ensures
@@ -24,7 +24,7 @@ import (
 // This only tests the dispatch mechanism. The underlying dispatchers must be
 // tested individually.
 func TestAppDispatcher(t *testing.T) {
-	driver := inmemory.New()
+	driver := testdriver.New()
 	ctx := context.Background()
 	registry, err := storage.NewRegistry(ctx, driver, storage.BlobDescriptorCacheProvider(memorycache.NewInMemoryBlobDescriptorCacheProvider(0)), storage.EnableDelete, storage.EnableRedirect)
 	if err != nil {
@@ -141,7 +141,7 @@ func TestNewApp(t *testing.T) {
 	ctx := context.Background()
 	config := configuration.Configuration{
 		Storage: configuration.Storage{
-			"inmemory": nil,
+			"testdriver": nil,
 			"maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{
 				"enabled": false,
 			}},
diff --git a/registry/handlers/hmac_test.go b/registry/handlers/hmac_test.go
index ce9af25d..366c7279 100644
--- a/registry/handlers/hmac_test.go
+++ b/registry/handlers/hmac_test.go
@@ -45,8 +45,8 @@ var secrets = []string{
 func TestLayerUploadTokens(t *testing.T) {
 	secret := hmacKey("supersecret")
 
-	for _, tc := range blobUploadStates {
-		token, err := secret.packUploadState(tc)
+	for _, testcase := range blobUploadStates {
+		token, err := secret.packUploadState(testcase)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -56,7 +56,7 @@ func TestLayerUploadTokens(t *testing.T) {
 			t.Fatal(err)
 		}
 
-		assertBlobUploadStateEquals(t, tc, lus)
+		assertBlobUploadStateEquals(t, testcase, lus)
 	}
 }
 
@@ -68,8 +68,8 @@ func TestHMACValidation(t *testing.T) {
 		secret2 := hmacKey(secret)
 		badSecret := hmacKey("DifferentSecret")
 
-		for _, tc := range blobUploadStates {
-			token, err := secret1.packUploadState(tc)
+		for _, testcase := range blobUploadStates {
+			token, err := secret1.packUploadState(testcase)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -79,7 +79,7 @@ func TestHMACValidation(t *testing.T) {
 				t.Fatal(err)
 			}
 
-			assertBlobUploadStateEquals(t, tc, lus)
+			assertBlobUploadStateEquals(t, testcase, lus)
 
 			_, err = badSecret.unpackUploadState(token)
 			if err == nil {
@@ -105,7 +105,6 @@ func TestHMACValidation(t *testing.T) {
 }
 
 func assertBlobUploadStateEquals(t *testing.T, expected blobUploadState, received blobUploadState) {
-	t.Helper()
 	if expected.Name != received.Name {
 		t.Fatalf("Expected Name=%q, Received Name=%q", expected.Name, received.Name)
 	}
diff --git a/registry/proxy/proxymanifeststore_test.go b/registry/proxy/proxymanifeststore_test.go
index 2e1bb142..bd06a49b 100644
--- a/registry/proxy/proxymanifeststore_test.go
+++ b/registry/proxy/proxymanifeststore_test.go
@@ -8,7 +8,7 @@ import (
 
 	"github.com/distribution/distribution/v3"
 	"github.com/distribution/distribution/v3/manifest"
-	"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	"github.com/distribution/distribution/v3/manifest/schema1"
 	"github.com/distribution/distribution/v3/reference"
 	"github.com/distribution/distribution/v3/registry/client/auth"
 	"github.com/distribution/distribution/v3/registry/client/auth/challenge"
@@ -151,7 +151,7 @@ func newManifestStoreTestEnv(t *testing.T, name, tag string) *manifestStoreTestE
 }
 
 func populateRepo(ctx context.Context, t *testing.T, repository distribution.Repository, name, tag string) (digest.Digest, error) {
-	m := schema1.Manifest{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	m := schema1.Manifest{
 		Versioned: manifest.Versioned{
 			SchemaVersion: 1,
 		},
@@ -183,7 +183,7 @@ func populateRepo(ctx context.Context, t *testing.T, repository distribution.Rep
 		t.Fatalf("unexpected error generating private key: %v", err)
 	}
 
-	sm, err := schema1.Sign(&m, pk) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	sm, err := schema1.Sign(&m, pk)
 	if err != nil {
 		t.Fatalf("error signing manifest: %v", err)
 	}
diff --git a/registry/storage/blob_test.go b/registry/storage/blob_test.go
index 01158255..6df9e700 100644
--- a/registry/storage/blob_test.go
+++ b/registry/storage/blob_test.go
@@ -13,7 +13,7 @@ import (
 	"github.com/distribution/distribution/v3"
 	"github.com/distribution/distribution/v3/reference"
 	"github.com/distribution/distribution/v3/registry/storage/cache/memory"
-	"github.com/distribution/distribution/v3/registry/storage/driver/inmemory"
+	"github.com/distribution/distribution/v3/registry/storage/driver/testdriver"
 	"github.com/distribution/distribution/v3/testutil"
 	"github.com/opencontainers/go-digest"
 )
@@ -23,7 +23,7 @@ import (
 func TestWriteSeek(t *testing.T) {
 	ctx := context.Background()
 	imageName, _ := reference.WithName("foo/bar")
-	driver := inmemory.New()
+	driver := testdriver.New()
 	registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider(memory.UnlimitedSize)), EnableDelete, EnableRedirect)
 	if err != nil {
 		t.Fatalf("error creating registry: %v", err)
@@ -57,7 +57,7 @@ func TestSimpleBlobUpload(t *testing.T) {
 
 	ctx := context.Background()
 	imageName, _ := reference.WithName("foo/bar")
-	driver := inmemory.New()
+	driver := testdriver.New()
 	registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider(memory.UnlimitedSize)), EnableDelete, EnableRedirect)
 	if err != nil {
 		t.Fatalf("error creating registry: %v", err)
@@ -251,7 +251,7 @@ func TestSimpleBlobUpload(t *testing.T) {
 func TestSimpleBlobRead(t *testing.T) {
 	ctx := context.Background()
 	imageName, _ := reference.WithName("foo/bar")
-	driver := inmemory.New()
+	driver := testdriver.New()
 	registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider(memory.UnlimitedSize)), EnableDelete, EnableRedirect)
 	if err != nil {
 		t.Fatalf("error creating registry: %v", err)
@@ -363,7 +363,7 @@ func TestBlobMount(t *testing.T) {
 	ctx := context.Background()
 	imageName, _ := reference.WithName("foo/bar")
 	sourceImageName, _ := reference.WithName("foo/source")
-	driver := inmemory.New()
+	driver := testdriver.New()
 	registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider(memory.UnlimitedSize)), EnableDelete, EnableRedirect)
 	if err != nil {
 		t.Fatalf("error creating registry: %v", err)
@@ -513,7 +513,7 @@ func TestBlobMount(t *testing.T) {
 func TestLayerUploadZeroLength(t *testing.T) {
 	ctx := context.Background()
 	imageName, _ := reference.WithName("foo/bar")
-	driver := inmemory.New()
+	driver := testdriver.New()
 	registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider(memory.UnlimitedSize)), EnableDelete, EnableRedirect)
 	if err != nil {
 		t.Fatalf("error creating registry: %v", err)
diff --git a/registry/storage/catalog_test.go b/registry/storage/catalog_test.go
index 14ba4e83..1b7bcd8c 100644
--- a/registry/storage/catalog_test.go
+++ b/registry/storage/catalog_test.go
@@ -93,7 +93,7 @@ func makeRepo(ctx context.Context, t *testing.T, name string, reg distribution.N
 		return
 	}
 
-	manifest, err := testutil.MakeSchema1Manifest(getKeys(layers)) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	manifest, err := testutil.MakeSchema1Manifest(getKeys(layers))
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/registry/storage/driver/middleware/cloudfront/s3filter_test.go b/registry/storage/driver/middleware/cloudfront/s3filter_test.go
index 81ef6aa8..3b0331b7 100644
--- a/registry/storage/driver/middleware/cloudfront/s3filter_test.go
+++ b/registry/storage/driver/middleware/cloudfront/s3filter_test.go
@@ -8,11 +8,12 @@ import (
 	"net"
 	"net/http"
 	"net/http/httptest"
-	"reflect" // used as a replacement for testify
 	"testing"
 	"time"
 
 	dcontext "github.com/distribution/distribution/v3/context"
+
+	"reflect" // used as a replacement for testify
 )
 
 // Rather than pull in all of testify
@@ -261,8 +262,7 @@ func TestUpdateCalledRegularly(t *testing.T) {
 }
 
 func TestEligibleForS3(t *testing.T) {
-	t.Parallel()
-	ips := &awsIPs{
+	awsIPs := &awsIPs{
 		ipv4: []net.IPNet{{
 			IP:   net.ParseIP("192.168.1.1"),
 			Mask: net.IPv4Mask(255, 255, 255, 0),
@@ -278,7 +278,7 @@ func TestEligibleForS3(t *testing.T) {
 		return dcontext.WithRequest(empty, req)
 	}
 
-	tests := []struct {
+	cases := []struct {
 		Context  context.Context
 		Expected bool
 	}{
@@ -287,18 +287,17 @@ func TestEligibleForS3(t *testing.T) {
 		{Context: makeContext("192.168.0.2"), Expected: false},
 	}
 
-	for _, tc := range tests {
-		tc := tc
-		t.Run(fmt.Sprintf("Client IP = %v", tc.Context.Value("http.request.ip")), func(t *testing.T) {
-			t.Parallel()
-			assertEqual(t, tc.Expected, eligibleForS3(tc.Context, ips))
+	for _, testCase := range cases {
+		name := fmt.Sprintf("Client IP = %v",
+			testCase.Context.Value("http.request.ip"))
+		t.Run(name, func(t *testing.T) {
+			assertEqual(t, testCase.Expected, eligibleForS3(testCase.Context, awsIPs))
 		})
 	}
 }
 
 func TestEligibleForS3WithAWSIPNotInitialized(t *testing.T) {
-	t.Parallel()
-	ips := &awsIPs{
+	awsIPs := &awsIPs{
 		ipv4: []net.IPNet{{
 			IP:   net.ParseIP("192.168.1.1"),
 			Mask: net.IPv4Mask(255, 255, 255, 0),
@@ -314,7 +313,7 @@ func TestEligibleForS3WithAWSIPNotInitialized(t *testing.T) {
 		return dcontext.WithRequest(empty, req)
 	}
 
-	tests := []struct {
+	cases := []struct {
 		Context  context.Context
 		Expected bool
 	}{
@@ -323,11 +322,11 @@ func TestEligibleForS3WithAWSIPNotInitialized(t *testing.T) {
 		{Context: makeContext("192.168.0.2"), Expected: false},
 	}
 
-	for _, tc := range tests {
-		tc := tc
-		t.Run(fmt.Sprintf("Client IP = %v", tc.Context.Value("http.request.ip")), func(t *testing.T) {
-			t.Parallel()
-			assertEqual(t, tc.Expected, eligibleForS3(tc.Context, ips))
+	for _, testCase := range cases {
+		name := fmt.Sprintf("Client IP = %v",
+			testCase.Context.Value("http.request.ip"))
+		t.Run(name, func(t *testing.T) {
+			assertEqual(t, testCase.Expected, eligibleForS3(testCase.Context, awsIPs))
 		})
 	}
 }
@@ -365,8 +364,8 @@ func BenchmarkContainsRandom(b *testing.B) {
 	numNetworksPerType := 1000 // keep in sync with the above
 	// intentionally skip constructor when creating awsIPs, to avoid updater routine.
 	// This benchmark is only concerned with contains() performance.
-	ips := awsIPs{}
-	populateRandomNetworks(b, &ips, numNetworksPerType, numNetworksPerType)
+	awsIPs := awsIPs{}
+	populateRandomNetworks(b, &awsIPs, numNetworksPerType, numNetworksPerType)
 
 	ipv4 := make([][]byte, b.N)
 	ipv6 := make([][]byte, b.N)
@@ -378,13 +377,13 @@ func BenchmarkContainsRandom(b *testing.B) {
 	}
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		ips.contains(ipv4[i])
-		ips.contains(ipv6[i])
+		awsIPs.contains(ipv4[i])
+		awsIPs.contains(ipv6[i])
 	}
 }
 
 func BenchmarkContainsProd(b *testing.B) {
-	ips := newAWSIPs(defaultIPRangesURL, defaultUpdateFrequency, nil)
+	awsIPs := newAWSIPs(defaultIPRangesURL, defaultUpdateFrequency, nil)
 	ipv4 := make([][]byte, b.N)
 	ipv6 := make([][]byte, b.N)
 	for i := 0; i < b.N; i++ {
@@ -395,7 +394,7 @@ func BenchmarkContainsProd(b *testing.B) {
 	}
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		ips.contains(ipv4[i])
-		ips.contains(ipv6[i])
+		awsIPs.contains(ipv4[i])
+		awsIPs.contains(ipv6[i])
 	}
 }
diff --git a/registry/storage/driver/testdriver/testdriver.go b/registry/storage/driver/testdriver/testdriver.go
new file mode 100644
index 00000000..63ed3e68
--- /dev/null
+++ b/registry/storage/driver/testdriver/testdriver.go
@@ -0,0 +1,72 @@
+package testdriver
+
+import (
+	"context"
+
+	storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
+	"github.com/distribution/distribution/v3/registry/storage/driver/factory"
+	"github.com/distribution/distribution/v3/registry/storage/driver/inmemory"
+)
+
+const driverName = "testdriver"
+
+func init() {
+	factory.Register(driverName, &testDriverFactory{})
+}
+
+// testDriverFactory implements the factory.StorageDriverFactory interface.
+type testDriverFactory struct{}
+
+func (factory *testDriverFactory) Create(parameters map[string]interface{}) (storagedriver.StorageDriver, error) {
+	return New(), nil
+}
+
+// TestDriver is a StorageDriver for testing purposes. The Writer returned by this driver
+// simulates the case where Write operations are buffered. This causes the value returned by Size to lag
+// behind until Close (or Commit, or Cancel) is called.
+type TestDriver struct {
+	storagedriver.StorageDriver
+}
+
+type testFileWriter struct {
+	storagedriver.FileWriter
+	prevchunk []byte
+}
+
+var _ storagedriver.StorageDriver = &TestDriver{}
+
+// New constructs a new StorageDriver for testing purposes. The Writer returned by this driver
+// simulates the case where Write operations are buffered. This causes the value returned by Size to lag
+// behind until Close (or Commit, or Cancel) is called.
+func New() *TestDriver {
+	return &TestDriver{StorageDriver: inmemory.New()}
+}
+
+// Writer returns a FileWriter which will store the content written to it
+// at the location designated by "path" after the call to Commit.
+func (td *TestDriver) Writer(ctx context.Context, path string, append bool) (storagedriver.FileWriter, error) {
+	fw, err := td.StorageDriver.Writer(ctx, path, append)
+	return &testFileWriter{FileWriter: fw}, err
+}
+
+func (tfw *testFileWriter) Write(p []byte) (int, error) {
+	_, err := tfw.FileWriter.Write(tfw.prevchunk)
+	tfw.prevchunk = make([]byte, len(p))
+	copy(tfw.prevchunk, p)
+	return len(p), err
+}
+
+func (tfw *testFileWriter) Close() error {
+	tfw.Write(nil)
+	return tfw.FileWriter.Close()
+}
+
+func (tfw *testFileWriter) Cancel(ctx context.Context) error {
+	tfw.Write(nil)
+	return tfw.FileWriter.Cancel(ctx)
+}
+
+func (tfw *testFileWriter) Commit() error {
+	tfw.Write(nil)
+	return tfw.FileWriter.Commit()
+}
diff --git a/registry/storage/garbagecollect_test.go b/registry/storage/garbagecollect_test.go
index bdbf9ab2..11088083 100644
--- a/registry/storage/garbagecollect_test.go
+++ b/registry/storage/garbagecollect_test.go
@@ -121,7 +121,7 @@ func uploadRandomSchema1Image(t *testing.T, repository distribution.Repository)
 		digests = append(digests, digest)
 	}
 
-	manifest, err := testutil.MakeSchema1Manifest(digests) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	manifest, err := testutil.MakeSchema1Manifest(digests)
 	if err != nil {
 		t.Fatalf("%v", err)
 	}
@@ -232,12 +232,12 @@ func TestDeleteManifestIfTagNotFound(t *testing.T) {
 	}
 
 	// Construct manifests
-	manifest1, err := testutil.MakeSchema1Manifest(getKeys(randomLayers1)) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	manifest1, err := testutil.MakeSchema1Manifest(getKeys(randomLayers1))
 	if err != nil {
 		t.Fatalf("failed to make manifest: %v", err)
 	}
 
-	manifest2, err := testutil.MakeSchema1Manifest(getKeys(randomLayers2)) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	manifest2, err := testutil.MakeSchema1Manifest(getKeys(randomLayers2))
 	if err != nil {
 		t.Fatalf("failed to make manifest: %v", err)
 	}
@@ -426,7 +426,7 @@ func TestDeletionWithSharedLayer(t *testing.T) {
 	}
 
 	// Construct manifests
-	manifest1, err := testutil.MakeSchema1Manifest(getKeys(randomLayers1)) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	manifest1, err := testutil.MakeSchema1Manifest(getKeys(randomLayers1))
 	if err != nil {
 		t.Fatalf("failed to make manifest: %v", err)
 	}
diff --git a/registry/storage/manifeststore_test.go b/registry/storage/manifeststore_test.go
index 0d7a4379..efcc80b6 100644
--- a/registry/storage/manifeststore_test.go
+++ b/registry/storage/manifeststore_test.go
@@ -11,7 +11,7 @@ import (
 	"github.com/distribution/distribution/v3/manifest"
 	"github.com/distribution/distribution/v3/manifest/manifestlist"
 	"github.com/distribution/distribution/v3/manifest/ocischema"
-	"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	"github.com/distribution/distribution/v3/manifest/schema1"
 	"github.com/distribution/distribution/v3/reference"
 	"github.com/distribution/distribution/v3/registry/storage/cache/memory"
 	"github.com/distribution/distribution/v3/registry/storage/driver"
@@ -79,7 +79,7 @@ func testManifestStorage(t *testing.T, schema1Enabled bool, options ...RegistryO
 		t.Fatal(err)
 	}
 
-	m := schema1.Manifest{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	m := schema1.Manifest{
 		Versioned: manifest.Versioned{
 			SchemaVersion: 1,
 		},
@@ -97,10 +97,10 @@ func testManifestStorage(t *testing.T, schema1Enabled bool, options ...RegistryO
 		}
 
 		testLayers[dgst] = rs
-		m.FSLayers = append(m.FSLayers, schema1.FSLayer{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+		m.FSLayers = append(m.FSLayers, schema1.FSLayer{
 			BlobSum: dgst,
 		})
-		m.History = append(m.History, schema1.History{ //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+		m.History = append(m.History, schema1.History{
 			V1Compatibility: "",
 		})
 
@@ -111,7 +111,7 @@ func testManifestStorage(t *testing.T, schema1Enabled bool, options ...RegistryO
 		t.Fatalf("unexpected error generating private key: %v", err)
 	}
 
-	sm, merr := schema1.Sign(&m, pk) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	sm, merr := schema1.Sign(&m, pk)
 	if merr != nil {
 		t.Fatalf("error signing manifest: %v", err)
 	}
@@ -180,7 +180,7 @@ func testManifestStorage(t *testing.T, schema1Enabled bool, options ...RegistryO
 		t.Fatalf("unexpected error fetching manifest: %v", err)
 	}
 
-	fetchedManifest, ok := fromStore.(*schema1.SignedManifest) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	fetchedManifest, ok := fromStore.(*schema1.SignedManifest)
 	if !ok {
 		t.Fatalf("unexpected manifest type from signedstore")
 	}
@@ -189,7 +189,7 @@ func testManifestStorage(t *testing.T, schema1Enabled bool, options ...RegistryO
 		t.Fatalf("fetched payload does not match original payload: %q != %q", fetchedManifest.Canonical, sm.Canonical)
 	}
 
-	_, pl, err := fetchedManifest.Payload() //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	_, pl, err := fetchedManifest.Payload()
 	if err != nil {
 		t.Fatalf("error getting payload %#v", err)
 	}
@@ -222,7 +222,7 @@ func testManifestStorage(t *testing.T, schema1Enabled bool, options ...RegistryO
 		t.Fatalf("unexpected error fetching manifest by digest: %v", err)
 	}
 
-	byDigestManifest, ok := fetchedByDigest.(*schema1.SignedManifest) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	byDigestManifest, ok := fetchedByDigest.(*schema1.SignedManifest)
 	if !ok {
 		t.Fatalf("unexpected manifest type from signedstore")
 	}
@@ -246,11 +246,11 @@ func testManifestStorage(t *testing.T, schema1Enabled bool, options ...RegistryO
 		t.Fatalf("unexpected error generating private key: %v", err)
 	}
 
-	sm2, err := schema1.Sign(&m, pk2) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	sm2, err := schema1.Sign(&m, pk2)
 	if err != nil {
 		t.Fatalf("unexpected error signing manifest: %v", err)
 	}
-	_, pl, err = sm2.Payload() //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	_, pl, err = sm2.Payload()
 	if err != nil {
 		t.Fatalf("error getting payload %#v", err)
 	}
@@ -278,16 +278,16 @@ func testManifestStorage(t *testing.T, schema1Enabled bool, options ...RegistryO
 		t.Fatalf("unexpected error fetching manifest: %v", err)
 	}
 
-	fetched, ok := fromStore.(*schema1.SignedManifest) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	fetched, ok := fromStore.(*schema1.SignedManifest)
 	if !ok {
 		t.Fatalf("unexpected type from signed manifeststore : %T", fetched)
 	}
 
-	if _, err := schema1.Verify(fetched); err != nil { //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	if _, err := schema1.Verify(fetched); err != nil {
 		t.Fatalf("unexpected error verifying manifest: %v", err)
 	}
 
-	_, pl, err = fetched.Payload() //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	_, pl, err = fetched.Payload()
 	if err != nil {
 		t.Fatalf("error getting payload %#v", err)
 	}
diff --git a/testutil/manifests.go b/testutil/manifests.go
index 2b421149..6d44930b 100644
--- a/testutil/manifests.go
+++ b/testutil/manifests.go
@@ -7,7 +7,7 @@ import (
 	"github.com/distribution/distribution/v3/context"
 	"github.com/distribution/distribution/v3/manifest"
 	"github.com/distribution/distribution/v3/manifest/manifestlist"
-	"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
+	"github.com/distribution/distribution/v3/manifest/schema1"
 	"github.com/distribution/distribution/v3/manifest/schema2"
 	"github.com/docker/libtrust"
 	"github.com/opencontainers/go-digest"
@@ -44,7 +44,7 @@ func MakeManifestList(blobstatter distribution.BlobStatter, manifestDigests []di
 //
 // Deprecated: Docker Image Manifest v2, Schema 1 is deprecated since 2015.
 // Use Docker Image Manifest v2, Schema 2, or the OCI Image Specification.
-func MakeSchema1Manifest(digests []digest.Digest) (distribution.Manifest, error) {
+func MakeSchema1Manifest(digests []digest.Digest) (*schema1.SignedManifest, error) {
 	mfst := schema1.Manifest{
 		Versioned: manifest.Versioned{
 			SchemaVersion: 1,
@@ -76,9 +76,16 @@ func MakeSchema1Manifest(digests []digest.Digest) (distribution.Manifest, error)
 func MakeSchema2Manifest(repository distribution.Repository, digests []digest.Digest) (distribution.Manifest, error) {
 	ctx := context.Background()
 	blobStore := repository.Blobs(ctx)
-	builder := schema2.NewManifestBuilder(blobStore, schema2.MediaTypeImageConfig, []byte{})
-	for _, d := range digests {
-		builder.AppendReference(distribution.Descriptor{Digest: d})
+
+	var configJSON []byte
+
+	d, err := blobStore.Put(ctx, schema2.MediaTypeImageConfig, configJSON)
+	if err != nil {
+		return nil, fmt.Errorf("unexpected error storing content in blobstore: %v", err)
+	}
+	builder := schema2.NewManifestBuilder(d, configJSON)
+	for _, digest := range digests {
+		builder.AppendReference(distribution.Descriptor{Digest: digest})
 	}
 
 	mfst, err := builder.Build(ctx)