Repository: weaviate/weaviate
Pull request #6976 (2025-01-21 09:47:44)

RBAC: Reduce amount of authorizer calls for reference batch
### What's being changed:

Get the classes at the top of the call stack once and pass them down instead of re-getting them everytime we need it. Each class-get is authorized and results in a call to the authorizer. 

Before:   batch ref created 151 calls to authorizer
After:   batch ref created 4 calls to authorizer

for a batch ref request with 30 refs with different from and to classes.

### Review checklist

- [ ] Documentation has been updated, if necessary. Link to changed documentation:
- [ ] Chaos pipeline run or not necessary. Link to pipeline:
  - e2e: https://github.com/weaviate/weaviate-e2e-tests/actions/runs/12886578853
  - chaos: https://github.com/weaviate/weaviate-chaos-engineering/actions/runs/12886592820
- [ ] All new code is covered by tests where it is reasonable.
- [ ] Performance tests have been run or not necessary.

<!-- Uncomment the following section if this PR requires changes in related projects (e.g., documentation, client libraries).

GitHub actions will automatically create an issue in the corresponding repository for each checked box below. (See `.github/workflows/create-cross-functional-issues.yml`)

### Cross-functional impact

- [ ] This change requires public documentation (weaviate-io) to be updated. Check the box to automatically create a corresponding issue.
- Does it require a change in the client libraries? If yes, please check the boxes for the affected client libraries.
    - [ ] Python (weaviate-python-client)
    - [ ] JavaScript/TypeScript (typescript-client)
    - [ ] Go (weaviate-go-client)
    - [ ] Java (java-client)

-->



Patch:
diff --git a/.golangci.yml b/.golangci.yml
index f2da1216c4..512d796e47 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -9,26 +9,11 @@ linters:
     - govet
     - unused
     - nolintlint
-    - errorlint
 linters-settings:
   exhaustive:
     # Presence of "default" case in switch statements satisfies exhaustiveness,
     # even if all enum members are not listed.
     default-signifies-exhaustive: true
-  errorlint:
-    # Check whether fmt.Errorf uses the %w verb for formatting errors.
-    # See the https://github.com/polyfloyd/go-errorlint for caveats.
-    # Default: true
-    errorf: true
-    # Permit more than 1 %w verb, valid per Go 1.20 (Requires errorf:true)
-    # Default: true
-    errorf-multi: true
-    # Check for plain type assertions and type switches.
-    # Default: true
-    asserts: true
-    # Check for plain error comparisons.
-    # Default: true
-    comparison: true
 issues:
   exclude-rules:
     # Exclude some staticcheck messages
diff --git a/adapters/clients/client.go b/adapters/clients/client.go
index 9be02f82e2..e9f6f2a230 100644
--- a/adapters/clients/client.go
+++ b/adapters/clients/client.go
@@ -119,7 +119,7 @@ func (r *retryer) retry(ctx context.Context, n int, work func(context.Context) (
 		select {
 		case <-ctx.Done():
 			timer.Stop()
-			return fmt.Errorf("%w: %w", err, ctx.Err())
+			return fmt.Errorf("%v: %w", err, ctx.Err())
 		case <-timer.C:
 		}
 		timer.Stop()
diff --git a/adapters/handlers/graphql/local/aggregate/aggregate.go b/adapters/handlers/graphql/local/aggregate/aggregate.go
index d4bc769412..60e19e888b 100644
--- a/adapters/handlers/graphql/local/aggregate/aggregate.go
+++ b/adapters/handlers/graphql/local/aggregate/aggregate.go
@@ -151,7 +151,7 @@ func classPropertyFields(class *models.Class) (graphql.Fields, error) {
 	for _, property := range class.Properties {
 		propertyType, err := schema.GetPropertyDataType(class, property.Name)
 		if err != nil {
-			return nil, fmt.Errorf("%s.%s: %w", class.Class, property.Name, err)
+			return nil, fmt.Errorf("%s.%s: %s", class.Class, property.Name, err)
 		}
 
 		convertedDataType, err := classPropertyField(*propertyType, class, property)
diff --git a/adapters/handlers/graphql/local/aggregate/properties.go b/adapters/handlers/graphql/local/aggregate/properties.go
index 16ddaecbb4..df69fe5fe2 100644
--- a/adapters/handlers/graphql/local/aggregate/properties.go
+++ b/adapters/handlers/graphql/local/aggregate/properties.go
@@ -154,7 +154,7 @@ func referencePropertyFields(class *models.Class,
 			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
 				ref, err := extractReferenceAggregation(p.Source)
 				if err != nil {
-					return nil, fmt.Errorf("ref property pointingTo: %w", err)
+					return nil, fmt.Errorf("ref property pointingTo: %v", err)
 				}
 
 				return ref.PointingTo, nil
@@ -245,7 +245,7 @@ func booleanResolver(extractor booleanExtractorFunc) func(p graphql.ResolveParam
 	return func(p graphql.ResolveParams) (interface{}, error) {
 		boolean, err := extractBooleanAggregation(p.Source)
 		if err != nil {
-			return nil, fmt.Errorf("boolean: %w", err)
+			return nil, fmt.Errorf("boolean: %v", err)
 		}
 
 		return extractor(*boolean), nil
@@ -324,7 +324,7 @@ func textResolver(extractor textExtractorFunc) func(p graphql.ResolveParams) (in
 	return func(p graphql.ResolveParams) (interface{}, error) {
 		text, err := extractTextAggregation(p.Source)
 		if err != nil {
-			return nil, fmt.Errorf("text: %w", err)
+			return nil, fmt.Errorf("text: %v", err)
 		}
 
 		return extractor(text)
@@ -433,7 +433,7 @@ func makeResolveNumericFieldAggregator(aggregator string) func(p graphql.Resolve
 	return func(p graphql.ResolveParams) (interface{}, error) {
 		num, err := extractNumericAggregation(p.Source)
 		if err != nil {
-			return nil, fmt.Errorf("numerical aggregator %s: %w", aggregator, err)
+			return nil, fmt.Errorf("numerical aggregator %s: %v", aggregator, err)
 		}
 
 		return num[aggregator], nil
@@ -457,7 +457,7 @@ func makeResolveDateFieldAggregator(aggregator string) func(p graphql.ResolvePar
 	return func(p graphql.ResolveParams) (interface{}, error) {
 		date, err := extractDateAggregation(p.Source)
 		if err != nil {
-			return nil, fmt.Errorf("date aggregator %s: %w", aggregator, err)
+			return nil, fmt.Errorf("date aggregator %s: %v", aggregator, err)
 		}
 
 		return date[aggregator], nil
diff --git a/adapters/handlers/graphql/local/common_filters/parse_filters_into_ast.go b/adapters/handlers/graphql/local/common_filters/parse_filters_into_ast.go
index 7f7f48dd84..48ab466bf1 100644
--- a/adapters/handlers/graphql/local/common_filters/parse_filters_into_ast.go
+++ b/adapters/handlers/graphql/local/common_filters/parse_filters_into_ast.go
@@ -30,7 +30,7 @@ func ExtractFilters(args map[string]interface{}, rootClass string) (*filters.Loc
 		whereMap := where.(map[string]interface{}) // guaranteed by GraphQL to be a map.
 		filter, err := filterMapToModel(whereMap)
 		if err != nil {
-			return nil, fmt.Errorf("failed to extract filters: %w", err)
+			return nil, fmt.Errorf("failed to extract filters: %s", err)
 		}
 
 		return filterext.Parse(filter, rootClass)
@@ -40,13 +40,13 @@ func ExtractFilters(args map[string]interface{}, rootClass string) (*filters.Loc
 func filterMapToModel(m map[string]interface{}) (*models.WhereFilter, error) {
 	b, err := json.Marshal(m)
 	if err != nil {
-		return nil, fmt.Errorf("failed convert map to models.WhereFilter: %w", err)
+		return nil, fmt.Errorf("failed convert map to models.WhereFilter: %s", err)
 	}
 
 	var filter WhereFilter
 	err = json.Unmarshal(b, &filter)
 	if err != nil {
-		return nil, fmt.Errorf("failed convert map to models.WhereFilter: %w", err)
+		return nil, fmt.Errorf("failed convert map to models.WhereFilter: %s", err)
 	}
 
 	return newConverter().do(&filter)
diff --git a/adapters/handlers/graphql/local/explore/concepts_resolver.go b/adapters/handlers/graphql/local/explore/concepts_resolver.go
index 915e6857af..b0e0a4fa08 100644
--- a/adapters/handlers/graphql/local/explore/concepts_resolver.go
+++ b/adapters/handlers/graphql/local/explore/concepts_resolver.go
@@ -95,7 +95,7 @@ func (r *resolver) resolveExplore(p graphql.ResolveParams) (interface{}, error)
 	if param, ok := p.Args["nearVector"]; ok {
 		extracted, _, err := common_filters.ExtractNearVector(param.(map[string]interface{}), nil)
 		if err != nil {
-			return nil, fmt.Errorf("failed to extract nearVector params: %w", err)
+			return nil, fmt.Errorf("failed to extract nearVector params: %s", err)
 		}
 		params.NearVector = &extracted
 	}
@@ -103,7 +103,7 @@ func (r *resolver) resolveExplore(p graphql.ResolveParams) (interface{}, error)
 	if param, ok := p.Args["nearObject"]; ok {
 		extracted, _, err := common_filters.ExtractNearObject(param.(map[string]interface{}))
 		if err != nil {
-			return nil, fmt.Errorf("failed to extract nearObject params: %w", err)
+			return nil, fmt.Errorf("failed to extract nearObject params: %s", err)
 		}
 		params.NearObject = &extracted
 	}
diff --git a/adapters/handlers/graphql/local/get/class_builder_fields.go b/adapters/handlers/graphql/local/get/class_builder_fields.go
index 94fc166e63..d39fc296cc 100644
--- a/adapters/handlers/graphql/local/get/class_builder_fields.go
+++ b/adapters/handlers/graphql/local/get/class_builder_fields.go
@@ -387,7 +387,7 @@ func (r *resolver) resolveGet(p graphql.ResolveParams, className string) (interf
 
 	filters, err := common_filters.ExtractFilters(p.Args, p.Info.FieldName)
 	if err != nil {
-		return nil, fmt.Errorf("could not extract filters: %w", err)
+		return nil, fmt.Errorf("could not extract filters: %s", err)
 	}
 	if filters != nil {
 		if err = common_filters.AuthorizeFilters(r.authorizer, filters.Root, principal); err != nil {
@@ -400,7 +400,7 @@ func (r *resolver) resolveGet(p graphql.ResolveParams, className string) (interf
 	if nearVector, ok := p.Args["nearVector"]; ok {
 		p, targetCombination, err := common_filters.ExtractNearVector(nearVector.(map[string]interface{}), nil)
 		if err != nil {
-			return nil, fmt.Errorf("failed to extract nearVector params: %w", err)
+			return nil, fmt.Errorf("failed to extract nearVector params: %s", err)
 		}
 		nearVectorParams = &p
 		targetVectorCombination = targetCombination
@@ -410,7 +410,7 @@ func (r *resolver) resolveGet(p graphql.ResolveParams, className string) (interf
 	if nearObject, ok := p.Args["nearObject"]; ok {
 		p, targetCombination, err := common_filters.ExtractNearObject(nearObject.(map[string]interface{}))
 		if err != nil {
-			return nil, fmt.Errorf("failed to extract nearObject params: %w", err)
+			return nil, fmt.Errorf("failed to extract nearObject params: %s", err)
 		}
 		nearObjectParams = &p
 		targetVectorCombination = targetCombination
diff --git a/adapters/handlers/graphql/schema.go b/adapters/handlers/graphql/schema.go
index d10292f7a2..f6d2894cbb 100644
--- a/adapters/handlers/graphql/schema.go
+++ b/adapters/handlers/graphql/schema.go
@@ -115,7 +115,7 @@ func buildGraphqlSchema(dbSchema *schema.Schema, logger logrus.FieldLogger,
 	}()
 
 	if err != nil {
-		return graphql.Schema{}, fmt.Errorf("Could not build GraphQL schema, because: %w", err)
+		return graphql.Schema{}, fmt.Errorf("Could not build GraphQL schema, because: %v", err)
 	}
 
 	return result, nil
diff --git a/adapters/handlers/grpc/server.go b/adapters/handlers/grpc/server.go
index ef488bbac3..06d0ac5b3f 100644
--- a/adapters/handlers/grpc/server.go
+++ b/adapters/handlers/grpc/server.go
@@ -155,7 +155,7 @@ func StartAndListen(s *GRPCServer, state *state.State) error {
 	state.Logger.WithField("action", "grpc_startup").
 		Infof("grpc server listening at %v", lis.Addr())
 	if err := s.Serve(lis); err != nil {
-		return fmt.Errorf("failed to serve: %w", err)
+		return fmt.Errorf("failed to serve: %v", err)
 	}
 
 	return nil
diff --git a/adapters/handlers/rest/clusterapi/indices.go b/adapters/handlers/rest/clusterapi/indices.go
index fae68beac0..296f184deb 100644
--- a/adapters/handlers/rest/clusterapi/indices.go
+++ b/adapters/handlers/rest/clusterapi/indices.go
@@ -22,14 +22,14 @@ import (
 	"strconv"
 	"time"
 
+	"github.com/weaviate/weaviate/entities/dto"
+
 	"github.com/go-openapi/strfmt"
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
-
 	reposdb "github.com/weaviate/weaviate/adapters/repos/db"
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/aggregation"
-	"github.com/weaviate/weaviate/entities/dto"
 	enterrors "github.com/weaviate/weaviate/entities/errors"
 	"github.com/weaviate/weaviate/entities/filters"
 	entschema "github.com/weaviate/weaviate/entities/schema"
diff --git a/adapters/handlers/rest/clusterapi/indices_payloads.go b/adapters/handlers/rest/clusterapi/indices_payloads.go
index b8ad79cdec..77da8a9b2f 100644
--- a/adapters/handlers/rest/clusterapi/indices_payloads.go
+++ b/adapters/handlers/rest/clusterapi/indices_payloads.go
@@ -21,16 +21,17 @@ import (
 	"net/http"
 	"time"
 
+	"github.com/weaviate/weaviate/entities/dto"
+
+	"github.com/weaviate/weaviate/usecases/byteops"
+
 	"github.com/go-openapi/strfmt"
 	"github.com/pkg/errors"
-
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/aggregation"
-	"github.com/weaviate/weaviate/entities/dto"
 	"github.com/weaviate/weaviate/entities/filters"
 	"github.com/weaviate/weaviate/entities/searchparams"
 	"github.com/weaviate/weaviate/entities/storobj"
-	"github.com/weaviate/weaviate/usecases/byteops"
 	"github.com/weaviate/weaviate/usecases/objects"
 	"github.com/weaviate/weaviate/usecases/scaler"
 )
@@ -211,7 +212,7 @@ func (p objectListPayload) Unmarshal(in []byte) ([]*storobj.Object, error) {
 
 	for {
 		_, err := r.Read(reusableLengthBuf)
-		if errors.Is(err, io.EOF) {
+		if err == io.EOF {
 			break
 		}
 		if err != nil {
@@ -289,7 +290,7 @@ func (p versionedObjectListPayload) Unmarshal(in []byte) ([]*objects.VObject, er
 
 	for {
 		_, err := r.Read(reusableLengthBuf)
-		if errors.Is(err, io.EOF) {
+		if err == io.EOF {
 			break
 		}
 		if err != nil {
diff --git a/adapters/handlers/rest/clusterapi/indices_replicas.go b/adapters/handlers/rest/clusterapi/indices_replicas.go
index a45cadea08..d75760a387 100644
--- a/adapters/handlers/rest/clusterapi/indices_replicas.go
+++ b/adapters/handlers/rest/clusterapi/indices_replicas.go
@@ -24,7 +24,6 @@ import (
 	"time"
 
 	"github.com/go-openapi/strfmt"
-
 	enterrors "github.com/weaviate/weaviate/entities/errors"
 	"github.com/weaviate/weaviate/entities/storobj"
 	"github.com/weaviate/weaviate/usecases/objects"
@@ -877,8 +876,8 @@ func (i *replicatedIndices) postRefs() http.Handler {
 
 func localIndexNotReady(resp replica.SimpleResponse) bool {
 	if err := resp.FirstError(); err != nil {
-		var replicaErr *replica.Error
-		if errors.As(err, &replicaErr) && replicaErr.IsStatusCode(replica.StatusNotReady) {
+		re, ok := err.(*replica.Error)
+		if ok && re.IsStatusCode(replica.StatusNotReady) {
 			return true
 		}
 	}
diff --git a/adapters/handlers/rest/clusterapi/nodes.go b/adapters/handlers/rest/clusterapi/nodes.go
index 94ca81cdaf..b782886d4f 100644
--- a/adapters/handlers/rest/clusterapi/nodes.go
+++ b/adapters/handlers/rest/clusterapi/nodes.go
@@ -17,7 +17,6 @@ import (
 	"fmt"
 	"net/http"
 	"regexp"
-	"strings"
 
 	"github.com/weaviate/weaviate/entities/models"
 	entschema "github.com/weaviate/weaviate/entities/schema"
@@ -83,10 +82,9 @@ func (s *nodes) incomingNodeStatus() http.Handler {
 
 		var className string
 
-		// url is /nodes/status[/className], where /className is optional
-		args := strings.Split(r.URL.Path, "/")
-		if len(args) == 4 {
-			className = args[3]
+		args := regxNodesClass.FindStringSubmatch(r.URL.Path)
+		if len(args) == 3 {
+			className = args[2]
 		}
 
 		output := verbosity.OutputMinimal
@@ -94,6 +92,7 @@ func (s *nodes) incomingNodeStatus() http.Handler {
 		if found && len(out) > 0 {
 			output = out[0]
 		}
+
 		nodeStatus, err := s.nodesManager.GetNodeStatus(r.Context(), className, output)
 		if err != nil {
 			http.Error(w, "/nodes fulfill request: "+err.Error(),
diff --git a/adapters/handlers/rest/configure_api.go b/adapters/handlers/rest/configure_api.go
index 047ec14b98..4911b17da1 100644
--- a/adapters/handlers/rest/configure_api.go
+++ b/adapters/handlers/rest/configure_api.go
@@ -26,6 +26,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/weaviate/fgprof"
+
 	"github.com/KimMachineGun/automemlimit/memlimit"
 	armonmetrics "github.com/armon/go-metrics"
 	armonprometheus "github.com/armon/go-metrics/prometheus"
@@ -35,12 +37,11 @@ import (
 	"github.com/go-openapi/swag"
 	"github.com/pbnjay/memory"
 	"github.com/pkg/errors"
+
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/prometheus/client_golang/prometheus/collectors/version"
 	"github.com/prometheus/client_golang/prometheus/promhttp"
 	"github.com/sirupsen/logrus"
-
-	"github.com/weaviate/fgprof"
 	"github.com/weaviate/weaviate/adapters/clients"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/authz"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/clusterapi"
@@ -591,7 +592,7 @@ func MakeAppState(ctx context.Context, options *swag.CommandLineOptionsGroup) *s
 		enterrors.GoWrapper(func() {
 			// wait until meta store is ready, as reindex tasks needs schema
 			<-storeReadyCtx.Done()
-			if errors.Is(context.Cause(storeReadyCtx), metaStoreReadyErr) {
+			if context.Cause(storeReadyCtx) == metaStoreReadyErr {
 				appState.Logger.
 					WithField("action", "startup").
 					Info("Reindexing inverted indexes")
@@ -870,7 +871,7 @@ func logger() *logrus.Logger {
 	}
 	logLevelStr := os.Getenv("LOG_LEVEL")
 	level, err := logLevelFromString(logLevelStr)
-	if errors.Is(err, logLevelNotRecognized) {
+	if err == logLevelNotRecognized {
 		logger.WithField("log_level_env", logLevelStr).Warn("log level not recognized, defaulting to info")
 		level = logrus.InfoLevel
 	}
diff --git a/adapters/handlers/rest/configure_server.go b/adapters/handlers/rest/configure_server.go
index 4967a75d94..faeb13a969 100644
--- a/adapters/handlers/rest/configure_server.go
+++ b/adapters/handlers/rest/configure_server.go
@@ -19,9 +19,7 @@ import (
 	"path/filepath"
 	"time"
 
-	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/adapters/handlers/graphql"
 	"github.com/weaviate/weaviate/adapters/handlers/graphql/utils"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/state"
@@ -63,7 +61,7 @@ func makeUpdateSchemaCall(appState *state.State) func(schema.Schema) {
 			appState.Modules,
 			appState.Authorizer,
 		)
-		if err != nil && !errors.Is(err, utils.ErrEmptySchema) {
+		if err != nil && err != utils.ErrEmptySchema {
 			appState.Logger.WithField("action", "graphql_rebuild").
 				WithError(err).Error("could not (re)build graphql provider")
 		}
diff --git a/adapters/handlers/rest/filterext/parse.go b/adapters/handlers/rest/filterext/parse.go
index 9acc1c692e..fcdc5a2eac 100644
--- a/adapters/handlers/rest/filterext/parse.go
+++ b/adapters/handlers/rest/filterext/parse.go
@@ -32,14 +32,14 @@ func Parse(in *models.WhereFilter, rootClass string) (*filters.LocalFilter, erro
 	if operator.OnValue() {
 		filter, err := parseValueFilter(in, operator, rootClass)
 		if err != nil {
-			return nil, fmt.Errorf("invalid where filter: %w", err)
+			return nil, fmt.Errorf("invalid where filter: %v", err)
 		}
 		return filter, nil
 	}
 
 	filter, err := parseNestedFilter(in, operator, rootClass)
 	if err != nil {
-		return nil, fmt.Errorf("invalid where filter: %w", err)
+		return nil, fmt.Errorf("invalid where filter: %v", err)
 	}
 	return filter, nil
 }
@@ -108,7 +108,7 @@ func parseOperands(ops []*models.WhereFilter, rootClass string) ([]filters.Claus
 	for i, operand := range ops {
 		res, err := Parse(operand, rootClass)
 		if err != nil {
-			return nil, fmt.Errorf("operand %d: %w", i, err)
+			return nil, fmt.Errorf("operand %d: %v", i, err)
 		}
 
 		out[i] = *res.Root
diff --git a/adapters/handlers/rest/handlers_backup.go b/adapters/handlers/rest/handlers_backup.go
index c421f1318a..b341d106cd 100644
--- a/adapters/handlers/rest/handlers_backup.go
+++ b/adapters/handlers/rest/handlers_backup.go
@@ -16,12 +16,11 @@ import (
 
 	"github.com/go-openapi/runtime/middleware"
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations/backups"
 	"github.com/weaviate/weaviate/entities/backup"
 	"github.com/weaviate/weaviate/entities/models"
-	authzerrors "github.com/weaviate/weaviate/usecases/auth/authorization/errors"
+	authZerrors "github.com/weaviate/weaviate/usecases/auth/authorization/errors"
 	ubak "github.com/weaviate/weaviate/usecases/backup"
 	"github.com/weaviate/weaviate/usecases/monitoring"
 )
@@ -111,11 +110,13 @@ func (s *backupHandlers) createBackup(params backups.BackupsCreateParams,
 	})
 	if err != nil {
 		s.metricRequestsTotal.logError("", err)
+		var forbidden authZerrors.Forbidden
+		var errUnprocessable backup.ErrUnprocessable
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &forbidden):
 			return backups.NewBackupsCreateForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &backup.ErrUnprocessable{}):
+		case errors.As(err, &errUnprocessable):
 			return backups.NewBackupsCreateUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -142,14 +143,17 @@ func (s *backupHandlers) createBackupStatus(params backups.BackupsCreateStatusPa
 	status, err := s.manager.BackupStatus(params.HTTPRequest.Context(), principal, params.Backend, params.ID, overrideBucket, overridePath)
 	if err != nil {
 		s.metricRequestsTotal.logError("", err)
+		var forbidden authZerrors.Forbidden
+		var errUnprocessable backup.ErrUnprocessable
+		var errNotFound backup.ErrNotFound
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &forbidden):
 			return backups.NewBackupsCreateStatusForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &backup.ErrUnprocessable{}):
+		case errors.As(err, &errUnprocessable):
 			return backups.NewBackupsCreateStatusUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &backup.ErrNotFound{}):
+		case errors.As(err, &errNotFound):
 			return backups.NewBackupsCreateStatusNotFound().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -191,14 +195,17 @@ func (s *backupHandlers) restoreBackup(params backups.BackupsRestoreParams,
 	})
 	if err != nil {
 		s.metricRequestsTotal.logError("", err)
+		var forbidden authZerrors.Forbidden
+		var errNotFound backup.ErrNotFound
+		var errUnprocessable backup.ErrUnprocessable
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &forbidden):
 			return backups.NewBackupsRestoreForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &backup.ErrNotFound{}):
+		case errors.As(err, &errNotFound):
 			return backups.NewBackupsRestoreNotFound().
 				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &backup.ErrUnprocessable{}):
+		case errors.As(err, &errUnprocessable):
 			return backups.NewBackupsRestoreUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -226,14 +233,17 @@ func (s *backupHandlers) restoreBackupStatus(params backups.BackupsRestoreStatus
 		params.HTTPRequest.Context(), principal, params.Backend, params.ID, overrideBucket, overridePath)
 	if err != nil {
 		s.metricRequestsTotal.logError("", err)
+		var forbidden authZerrors.Forbidden
+		var errNotFound backup.ErrNotFound
+		var errUnprocessable backup.ErrUnprocessable
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &forbidden):
 			return backups.NewBackupsRestoreForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &backup.ErrNotFound{}):
+		case errors.As(err, &errNotFound):
 			return backups.NewBackupsRestoreNotFound().
 				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &backup.ErrUnprocessable{}):
+		case errors.As(err, &errUnprocessable):
 			return backups.NewBackupsRestoreUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -267,11 +277,13 @@ func (s *backupHandlers) cancel(params backups.BackupsCancelParams,
 	err := s.manager.Cancel(params.HTTPRequest.Context(), principal, params.Backend, params.ID, overrideBucket, overridePath)
 	if err != nil {
 		s.metricRequestsTotal.logError("", err)
+		var forbidden authZerrors.Forbidden
+		var errUnprocessable backup.ErrUnprocessable
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &forbidden):
 			return backups.NewBackupsCancelForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &backup.ErrUnprocessable{}):
+		case errors.As(err, &errUnprocessable):
 			return backups.NewBackupsCancelUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -291,12 +303,13 @@ func (s *backupHandlers) list(params backups.BackupsListParams,
 		params.HTTPRequest.Context(), principal, params.Backend)
 	if err != nil {
 		s.metricRequestsTotal.logError("", err)
+		var forbidden authZerrors.Forbidden
+		var errUnprocessable backup.ErrUnprocessable
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &forbidden):
 			return backups.NewBackupsRestoreForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
-
-		case errors.As(err, &backup.ErrUnprocessable{}):
+		case errors.As(err, &errUnprocessable):
 			return backups.NewBackupsRestoreUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -336,10 +349,10 @@ func newBackupRequestsTotal(metrics *monitoring.PrometheusMetrics, logger logrus
 }
 
 func (e *backupRequestsTotal) logError(className string, err error) {
-	switch {
-	case errors.As(err, &authzerrors.Forbidden{}):
+	switch err.(type) {
+	case authZerrors.Forbidden:
 		e.logUserError(className)
-	case errors.As(err, &backup.ErrUnprocessable{}) || errors.As(err, &backup.ErrNotFound{}):
+	case backup.ErrUnprocessable, backup.ErrNotFound:
 		e.logUserError(className)
 	default:
 		e.logServerError(className, err)
diff --git a/adapters/handlers/rest/handlers_batch_objects.go b/adapters/handlers/rest/handlers_batch_objects.go
index 3a19c7e631..17e2505257 100644
--- a/adapters/handlers/rest/handlers_batch_objects.go
+++ b/adapters/handlers/rest/handlers_batch_objects.go
@@ -17,7 +17,6 @@ import (
 	middleware "github.com/go-openapi/runtime/middleware"
 	"github.com/go-openapi/strfmt"
 	"github.com/sirupsen/logrus"
-
 	restCtx "github.com/weaviate/weaviate/adapters/handlers/rest/context"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations/batch"
@@ -48,14 +47,17 @@ func (h *batchObjectHandlers) addObjects(params batch.BatchObjectsCreateParams,
 		params.Body.Objects, params.Body.Fields, repl)
 	if err != nil {
 		h.metricRequestsTotal.logError("", err)
+		var forbidden autherrs.Forbidden
+		var errInvalidUserInput objects.ErrInvalidUserInput
+		var errMultiTenancy objects.ErrMultiTenancy
 		switch {
-		case errors.As(err, &autherrs.Forbidden{}):
+		case errors.As(err, &forbidden):
 			return batch.NewBatchObjectsCreateForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &objects.ErrInvalidUserInput{}):
+		case errors.As(err, &errInvalidUserInput):
 			return batch.NewBatchObjectsCreateUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &objects.ErrMultiTenancy{}):
+		case errors.As(err, &errMultiTenancy):
 			return batch.NewBatchObjectsCreateUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -106,14 +108,17 @@ func (h *batchObjectHandlers) addReferences(params batch.BatchReferencesCreatePa
 	references, err := h.manager.AddReferences(ctx, principal, params.Body, repl)
 	if err != nil {
 		h.metricRequestsTotal.logError("", err)
+		var forbidden autherrs.Forbidden
+		var errInvalidUserInput objects.ErrInvalidUserInput
+		var errMultiTenancy objects.ErrMultiTenancy
 		switch {
-		case errors.As(err, &autherrs.Forbidden{}):
+		case errors.As(err, &forbidden):
 			return batch.NewBatchReferencesCreateForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &objects.ErrInvalidUserInput{}):
+		case errors.As(err, &errInvalidUserInput):
 			return batch.NewBatchReferencesCreateUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &objects.ErrMultiTenancy{}):
+		case errors.As(err, &errMultiTenancy):
 			return batch.NewBatchReferencesCreateUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -266,12 +271,12 @@ func newBatchRequestsTotal(metrics *monitoring.PrometheusMetrics, logger logrus.
 }
 
 func (e *batchRequestsTotal) logError(className string, err error) {
-	switch {
-	case errors.As(err, &errReplication{}):
+	switch err.(type) {
+	case errReplication:
 		e.logUserError(className)
-	case errors.As(err, &autherrs.Forbidden{}), errors.As(err, &objects.ErrInvalidUserInput{}):
+	case autherrs.Forbidden, objects.ErrInvalidUserInput:
 		e.logUserError(className)
-	case errors.As(err, &objects.ErrMultiTenancy{}):
+	case objects.ErrMultiTenancy:
 		e.logUserError(className)
 	default:
 		if errors.As(err, &objects.ErrMultiTenancy{}) ||
diff --git a/adapters/handlers/rest/handlers_classification.go b/adapters/handlers/rest/handlers_classification.go
index f05f35fbb1..f2c1db1765 100644
--- a/adapters/handlers/rest/handlers_classification.go
+++ b/adapters/handlers/rest/handlers_classification.go
@@ -16,7 +16,6 @@ import (
 	"github.com/go-openapi/strfmt"
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations/classifications"
 	"github.com/weaviate/weaviate/entities/models"
@@ -87,5 +86,8 @@ func newClassificationRequestsTotal(metrics *monitoring.PrometheusMetrics, logge
 }
 
 func (e *classificationRequestsTotal) logError(className string, err error) {
-	e.logServerError(className, err)
+	switch err.(type) {
+	default:
+		e.logServerError(className, err)
+	}
 }
diff --git a/adapters/handlers/rest/handlers_graphql.go b/adapters/handlers/rest/handlers_graphql.go
index ee6ced0ee3..bbb2a66da0 100644
--- a/adapters/handlers/rest/handlers_graphql.go
+++ b/adapters/handlers/rest/handlers_graphql.go
@@ -24,7 +24,6 @@ import (
 	"github.com/sirupsen/logrus"
 	tailorincgraphql "github.com/tailor-inc/graphql"
 	"github.com/tailor-inc/graphql/gqlerrors"
-
 	libgraphql "github.com/weaviate/weaviate/adapters/handlers/graphql"
 	restCtx "github.com/weaviate/weaviate/adapters/handlers/rest/context"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations"
@@ -32,7 +31,7 @@ import (
 	enterrors "github.com/weaviate/weaviate/entities/errors"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/usecases/auth/authorization"
-	authzerrors "github.com/weaviate/weaviate/usecases/auth/authorization/errors"
+	authZerrors "github.com/weaviate/weaviate/usecases/auth/authorization/errors"
 	"github.com/weaviate/weaviate/usecases/monitoring"
 	"github.com/weaviate/weaviate/usecases/schema"
 )
@@ -64,8 +63,9 @@ func setupGraphQLHandlers(
 		err := m.Authorizer.Authorize(principal, authorization.READ, authorization.CollectionsMetadata()...)
 		if err != nil {
 			metricRequestsTotal.logUserError()
+			var forbidden authZerrors.Forbidden
 			switch {
-			case errors.As(err, &authzerrors.Forbidden{}):
+			case errors.As(err, &forbidden):
 				return graphql.NewGraphqlPostForbidden().
 					WithPayload(errPayloadFromSingleErr(err))
 			default:
@@ -315,15 +315,13 @@ func (e *graphqlRequestsTotal) getClassName(path []interface{}) string {
 
 func (e *graphqlRequestsTotal) getErrGraphQLUser(gqlError gqlerrors.FormattedError) (bool, *enterrors.ErrGraphQLUser) {
 	if gqlError.OriginalError() != nil {
-		var gqlOriginalErr *gqlerrors.Error
-		if errors.As(gqlError.OriginalError(), &gqlOriginalErr) {
+		if gqlOriginalErr, ok := gqlError.OriginalError().(*gqlerrors.Error); ok {
 			if gqlOriginalErr.OriginalError != nil {
-				switch {
-				case errors.As(gqlOriginalErr.OriginalError, &enterrors.ErrGraphQLUser{}):
-					return e.getError(gqlOriginalErr.OriginalError)
+				switch err := gqlOriginalErr.OriginalError.(type) {
+				case enterrors.ErrGraphQLUser:
+					return e.getError(err)
 				default:
-					var gqlFormatted *gqlerrors.FormattedError
-					if errors.As(gqlOriginalErr.OriginalError, &gqlFormatted) {
+					if gqlFormatted, ok := gqlOriginalErr.OriginalError.(gqlerrors.FormattedError); ok {
 						if gqlFormatted.OriginalError() != nil {
 							return e.getError(gqlFormatted.OriginalError())
 						}
@@ -345,10 +343,9 @@ func (e *graphqlRequestsTotal) isSyntaxRelatedError(gqlError gqlerrors.Formatted
 }
 
 func (e *graphqlRequestsTotal) getError(err error) (bool, *enterrors.ErrGraphQLUser) {
-	var errGraphQLUser *enterrors.ErrGraphQLUser
-	switch {
-	case errors.As(err, &errGraphQLUser):
-		return true, errGraphQLUser
+	switch e := err.(type) {
+	case enterrors.ErrGraphQLUser:
+		return true, &e
 	default:
 		return false, nil
 	}
diff --git a/adapters/handlers/rest/handlers_misc.go b/adapters/handlers/rest/handlers_misc.go
index c26cf06aaa..7bdf155720 100644
--- a/adapters/handlers/rest/handlers_misc.go
+++ b/adapters/handlers/rest/handlers_misc.go
@@ -17,7 +17,6 @@ import (
 
 	middleware "github.com/go-openapi/runtime/middleware"
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations/meta"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations/well_known"
@@ -141,5 +140,8 @@ func newMiscRequestsTotal(metrics *monitoring.PrometheusMetrics, logger logrus.F
 }
 
 func (e *miscRequestsTotal) logError(className string, err error) {
-	e.logServerError(className, err)
+	switch err.(type) {
+	default:
+		e.logServerError(className, err)
+	}
 }
diff --git a/adapters/handlers/rest/handlers_nodes.go b/adapters/handlers/rest/handlers_nodes.go
index e436171660..90ad74acd8 100644
--- a/adapters/handlers/rest/handlers_nodes.go
+++ b/adapters/handlers/rest/handlers_nodes.go
@@ -16,7 +16,6 @@ import (
 
 	"github.com/go-openapi/runtime/middleware"
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations/cluster"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations/nodes"
@@ -144,10 +143,10 @@ func newNodesRequestsTotal(metrics *monitoring.PrometheusMetrics, logger logrus.
 }
 
 func (e *nodesRequestsTotal) logError(className string, err error) {
-	switch {
-	case errors.As(err, &enterrors.ErrNotFound{}), errors.As(err, &enterrors.ErrUnprocessable{}):
+	switch err.(type) {
+	case enterrors.ErrNotFound, enterrors.ErrUnprocessable:
 		e.logUserError(className)
-	case errors.As(err, &autherrs.Forbidden{}):
+	case autherrs.Forbidden:
 		e.logUserError(className)
 	default:
 		e.logServerError(className, err)
diff --git a/adapters/handlers/rest/handlers_objects.go b/adapters/handlers/rest/handlers_objects.go
index 67e648400a..59861414c4 100644
--- a/adapters/handlers/rest/handlers_objects.go
+++ b/adapters/handlers/rest/handlers_objects.go
@@ -20,14 +20,13 @@ import (
 	middleware "github.com/go-openapi/runtime/middleware"
 	"github.com/go-openapi/strfmt"
 	"github.com/sirupsen/logrus"
-
 	restCtx "github.com/weaviate/weaviate/adapters/handlers/rest/context"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations/objects"
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/entities/schema/crossref"
-	authzerrors "github.com/weaviate/weaviate/usecases/auth/authorization/errors"
+	authzerrs "github.com/weaviate/weaviate/usecases/auth/authorization/errors"
 	"github.com/weaviate/weaviate/usecases/config"
 	"github.com/weaviate/weaviate/usecases/monitoring"
 	uco "github.com/weaviate/weaviate/usecases/objects"
@@ -99,7 +98,7 @@ func (h *objectHandlers) addObject(params objects.ObjectsCreateParams,
 		} else if errors.As(err, &uco.ErrMultiTenancy{}) {
 			return objects.NewObjectsCreateUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
-		} else if errors.As(err, &authzerrors.Forbidden{}) {
+		} else if errors.As(err, &authzerrs.Forbidden{}) {
 			return objects.NewObjectsCreateForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		} else {
@@ -125,17 +124,18 @@ func (h *objectHandlers) validateObject(params objects.ObjectsValidateParams,
 	err := h.manager.ValidateObject(ctx, principal, params.Body, nil)
 	if err != nil {
 		h.metricRequestsTotal.logError(className, err)
-		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
-			return objects.NewObjectsValidateForbidden().
-				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &uco.ErrInvalidUserInput{}):
+		switch err.(type) {
+		case uco.ErrInvalidUserInput:
 			return objects.NewObjectsValidateUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &uco.ErrMultiTenancy{}):
+		case uco.ErrMultiTenancy:
 			return objects.NewObjectsValidateUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
+			if errors.As(err, &authzerrs.Forbidden{}) {
+				return objects.NewObjectsValidateForbidden().
+					WithPayload(errPayloadFromSingleErr(err))
+			}
 			return objects.NewObjectsValidateInternalServerError().
 				WithPayload(errPayloadFromSingleErr(err))
 		}
@@ -193,16 +193,19 @@ func (h *objectHandlers) getObject(params objects.ObjectsClassGetParams,
 		params.ClassName, params.ID, additional, replProps, tenant)
 	if err != nil {
 		h.metricRequestsTotal.logError(getClassName(object), err)
+		var errNotFound uco.ErrNotFound
+		var errMultiTenancy uco.ErrMultiTenancy
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
-			return objects.NewObjectsClassGetForbidden().
-				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &uco.ErrNotFound{}):
+		case errors.As(err, &errNotFound):
 			return objects.NewObjectsClassGetNotFound()
-		case errors.As(err, &uco.ErrMultiTenancy{}):
+		case errors.As(err, &errMultiTenancy):
 			return objects.NewObjectsClassGetUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
+			if errors.As(err, &authzerrs.Forbidden{}) {
+				return objects.NewObjectsClassGetForbidden().
+					WithPayload(errPayloadFromSingleErr(err))
+			}
 			return objects.NewObjectsClassGetInternalServerError().
 				WithPayload(errPayloadFromSingleErr(err))
 		}
@@ -238,14 +241,15 @@ func (h *objectHandlers) getObjects(params objects.ObjectsListParams,
 		getTenant(params.Tenant))
 	if err != nil {
 		h.metricRequestsTotal.logError("", err)
-		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
-			return objects.NewObjectsListForbidden().
-				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &uco.ErrMultiTenancy{}):
+		switch err.(type) {
+		case uco.ErrMultiTenancy:
 			return objects.NewObjectsListUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
+			if errors.As(err, &authzerrs.Forbidden{}) {
+				return objects.NewObjectsListForbidden().
+					WithPayload(errPayloadFromSingleErr(err))
+			}
 			return objects.NewObjectsListInternalServerError().
 				WithPayload(errPayloadFromSingleErr(err))
 		}
@@ -342,16 +346,17 @@ func (h *objectHandlers) deleteObject(params objects.ObjectsClassDeleteParams,
 		principal, params.ClassName, params.ID, repl, tenant)
 	if err != nil {
 		h.metricRequestsTotal.logError(params.ClassName, err)
-		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
-			return objects.NewObjectsClassDeleteForbidden().
-				WithPayload(errPayloadFromSingleErr(err))
-		case errors.As(err, &uco.ErrNotFound{}):
+		switch err.(type) {
+		case uco.ErrNotFound:
 			return objects.NewObjectsClassDeleteNotFound()
-		case errors.As(err, &uco.ErrMultiTenancy{}):
+		case uco.ErrMultiTenancy:
 			return objects.NewObjectsClassDeleteUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
+			if errors.As(err, &authzerrs.Forbidden{}) {
+				return objects.NewObjectsClassDeleteForbidden().
+					WithPayload(errPayloadFromSingleErr(err))
+			}
 			return objects.NewObjectsClassDeleteInternalServerError().
 				WithPayload(errPayloadFromSingleErr(err))
 		}
@@ -383,7 +388,7 @@ func (h *objectHandlers) updateObject(params objects.ObjectsClassPutParams,
 		} else if errors.As(err, &uco.ErrMultiTenancy{}) {
 			return objects.NewObjectsClassPutUnprocessableEntity().
 				WithPayload(errPayloadFromSingleErr(err))
-		} else if errors.As(err, &authzerrors.Forbidden{}) {
+		} else if errors.As(err, &authzerrs.Forbidden{}) {
 			return objects.NewObjectsClassPutForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		} else {
@@ -814,19 +819,17 @@ func newObjectsRequestsTotal(metrics *monitoring.PrometheusMetrics, logger logru
 }
 
 func (e *objectsRequestsTotal) logError(className string, err error) {
-	var customError *uco.Error
-	switch {
-
-	case errors.As(err, &uco.ErrMultiTenancy{}):
+	switch err := err.(type) {
+	case uco.ErrMultiTenancy:
 		e.logUserError(className)
-	case errors.As(err, &errReplication{}), errors.As(err, &errUnregonizedProperty{}):
+	case errReplication, errUnregonizedProperty:
 		e.logUserError(className)
-	case errors.As(err, &authzerrors.Forbidden{}):
+	case authzerrs.Forbidden:
 		e.logUserError(className)
-	case errors.As(err, &uco.ErrInvalidUserInput{}), errors.As(err, &uco.ErrNotFound{}):
+	case uco.ErrInvalidUserInput, uco.ErrNotFound:
 		e.logUserError(className)
-	case errors.As(err, &customError):
-		switch customError.Code {
+	case *uco.Error:
+		switch err.Code {
 		case uco.StatusInternalServerError:
 			e.logServerError(className, err)
 		default:
@@ -835,7 +838,7 @@ func (e *objectsRequestsTotal) logError(className string, err error) {
 	default:
 		if errors.As(err, &uco.ErrInvalidUserInput{}) ||
 			errors.As(err, &uco.ErrMultiTenancy{}) ||
-			errors.As(err, &authzerrors.Forbidden{}) {
+			errors.As(err, &authzerrs.Forbidden{}) {
 			e.logUserError(className)
 		} else {
 			e.logServerError(className, err)
diff --git a/adapters/handlers/rest/handlers_schema.go b/adapters/handlers/rest/handlers_schema.go
index de3cdd4914..532b542a8c 100644
--- a/adapters/handlers/rest/handlers_schema.go
+++ b/adapters/handlers/rest/handlers_schema.go
@@ -17,12 +17,11 @@ import (
 
 	"github.com/go-openapi/runtime/middleware"
 	"github.com/sirupsen/logrus"
-
 	restCtx "github.com/weaviate/weaviate/adapters/handlers/rest/context"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations"
 	"github.com/weaviate/weaviate/adapters/handlers/rest/operations/schema"
 	"github.com/weaviate/weaviate/entities/models"
-	authzerrors "github.com/weaviate/weaviate/usecases/auth/authorization/errors"
+	authErrors "github.com/weaviate/weaviate/usecases/auth/authorization/errors"
 	"github.com/weaviate/weaviate/usecases/monitoring"
 	uco "github.com/weaviate/weaviate/usecases/objects"
 	schemaUC "github.com/weaviate/weaviate/usecases/schema"
@@ -41,7 +40,7 @@ func (s *schemaHandlers) addClass(params schema.SchemaObjectsCreateParams,
 	if err != nil {
 		s.metricRequestsTotal.logError(params.ObjectClass.Class, err)
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewSchemaObjectsCreateForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -62,12 +61,12 @@ func (s *schemaHandlers) updateClass(params schema.SchemaObjectsUpdateParams,
 		params.ObjectClass)
 	if err != nil {
 		s.metricRequestsTotal.logError(params.ClassName, err)
-		if errors.Is(err, schemaUC.ErrNotFound) {
+		if err == schemaUC.ErrNotFound {
 			return schema.NewSchemaObjectsUpdateNotFound()
 		}
 
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewSchemaObjectsUpdateForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -88,7 +87,7 @@ func (s *schemaHandlers) getClass(params schema.SchemaObjectsGetParams,
 	if err != nil {
 		s.metricRequestsTotal.logError(params.ClassName, err)
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewSchemaObjectsGetForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -111,7 +110,7 @@ func (s *schemaHandlers) deleteClass(params schema.SchemaObjectsDeleteParams, pr
 	if err != nil {
 		s.metricRequestsTotal.logError(params.ClassName, err)
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewSchemaObjectsDeleteForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -131,7 +130,7 @@ func (s *schemaHandlers) addClassProperty(params schema.SchemaObjectsPropertiesA
 	if err != nil {
 		s.metricRequestsTotal.logError(params.ClassName, err)
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewSchemaObjectsPropertiesAddForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -149,7 +148,7 @@ func (s *schemaHandlers) getSchema(params schema.SchemaDumpParams, principal *mo
 	if err != nil {
 		s.metricRequestsTotal.logError("", err)
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewSchemaDumpForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -178,7 +177,7 @@ func (s *schemaHandlers) getShardsStatus(params schema.SchemaObjectsShardsGetPar
 	if err != nil {
 		s.metricRequestsTotal.logError("", err)
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewSchemaObjectsShardsGetForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -202,7 +201,7 @@ func (s *schemaHandlers) updateShardStatus(params schema.SchemaObjectsShardsUpda
 	if err != nil {
 		s.metricRequestsTotal.logError("", err)
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewSchemaObjectsShardsGetForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -226,7 +225,7 @@ func (s *schemaHandlers) createTenants(params schema.TenantsCreateParams,
 	if err != nil {
 		s.metricRequestsTotal.logError(params.ClassName, err)
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewTenantsCreateForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -248,7 +247,7 @@ func (s *schemaHandlers) updateTenants(params schema.TenantsUpdateParams,
 	if err != nil {
 		s.metricRequestsTotal.logError(params.ClassName, err)
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewTenantsUpdateForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -270,7 +269,7 @@ func (s *schemaHandlers) deleteTenants(params schema.TenantsDeleteParams,
 	if err != nil {
 		s.metricRequestsTotal.logError(params.ClassName, err)
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewTenantsDeleteForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -291,7 +290,7 @@ func (s *schemaHandlers) getTenants(params schema.TenantsGetParams,
 	if err != nil {
 		s.metricRequestsTotal.logError(params.ClassName, err)
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewTenantsGetForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -313,7 +312,7 @@ func (s *schemaHandlers) getTenant(
 	if err != nil {
 		s.metricRequestsTotal.logError(params.ClassName, err)
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewTenantsGetOneForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -344,7 +343,7 @@ func (s *schemaHandlers) tenantExists(params schema.TenantExistsParams, principa
 			return schema.NewTenantExistsNotFound()
 		}
 		switch {
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &authErrors.Forbidden{}):
 			return schema.NewTenantExistsForbidden().
 				WithPayload(errPayloadFromSingleErr(err))
 		default:
@@ -399,7 +398,7 @@ func newSchemaRequestsTotal(metrics *monitoring.PrometheusMetrics, logger logrus
 
 func (e *schemaRequestsTotal) logError(className string, err error) {
 	switch {
-	case errors.As(err, &authzerrors.Forbidden{}):
+	case errors.As(err, &authErrors.Forbidden{}):
 		e.logUserError(className)
 	case errors.As(err, &uco.ErrMultiTenancy{}):
 		e.logUserError(className)
diff --git a/adapters/handlers/rest/raft/handler.go b/adapters/handlers/rest/raft/handler.go
index 6bf389acf2..aa6fedd2b1 100644
--- a/adapters/handlers/rest/raft/handler.go
+++ b/adapters/handlers/rest/raft/handler.go
@@ -14,7 +14,6 @@ package raft
 import (
 	"context"
 	"encoding/json"
-	"errors"
 	"fmt"
 	"io"
 	"net/http"
@@ -58,7 +57,7 @@ func (h RaftHandler) JoinNode(w http.ResponseWriter, r *http.Request) {
 	err := json.NewDecoder(r.Body).Decode(&joinRequest)
 	if err != nil {
 		errString := err.Error()
-		if errors.Is(err, io.EOF) {
+		if err == io.EOF {
 			// Nicer error message than "EOF"
 			errString = "request body is empty"
 		}
@@ -117,7 +116,7 @@ func (h RaftHandler) RemoveNode(w http.ResponseWriter, r *http.Request) {
 	err := json.NewDecoder(r.Body).Decode(&removeRequest)
 	if err != nil {
 		errString := err.Error()
-		if errors.Is(err, io.EOF) {
+		if err == io.EOF {
 			// Nicer error message than "EOF"
 			errString = "request body is empty"
 		}
diff --git a/adapters/repos/db/aggregator/date.go b/adapters/repos/db/aggregator/date.go
index 3ca43b1898..da06d3e183 100644
--- a/adapters/repos/db/aggregator/date.go
+++ b/adapters/repos/db/aggregator/date.go
@@ -111,7 +111,7 @@ type timestampCountPair struct {
 func (a *dateAggregator) AddTimestamp(rfc3339 string) error {
 	t, err := time.Parse(time.RFC3339Nano, rfc3339)
 	if err != nil {
-		return fmt.Errorf("failed to parse timestamp: %w", err)
+		return fmt.Errorf("failed to parse timestamp: %s", err)
 	}
 
 	ts := timestamp{
diff --git a/adapters/repos/db/aggregator/filtered.go b/adapters/repos/db/aggregator/filtered.go
index f98ef69680..f205235431 100644
--- a/adapters/repos/db/aggregator/filtered.go
+++ b/adapters/repos/db/aggregator/filtered.go
@@ -184,7 +184,7 @@ func (fa *filteredAggregator) AnalyzeObject(ctx context.Context,
 		}
 
 		if err := fa.addPropValue(prop, value); err != nil {
-			return fmt.Errorf("failed to add prop value: %w", err)
+			return fmt.Errorf("failed to add prop value: %s", err)
 		}
 	}
 
diff --git a/adapters/repos/db/crud.go b/adapters/repos/db/crud.go
index 26ab9680af..d44d12a57f 100644
--- a/adapters/repos/db/crud.go
+++ b/adapters/repos/db/crud.go
@@ -18,7 +18,6 @@ import (
 	"time"
 
 	"github.com/go-openapi/strfmt"
-
 	"github.com/weaviate/weaviate/adapters/repos/db/refcache"
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/models"
@@ -138,8 +137,8 @@ func (db *DB) ObjectsByID(ctx context.Context, id strfmt.UUID,
 		res, err := index.objectByID(ctx, id, props, additional, nil, tenant)
 		if err != nil {
 			db.indexLock.RUnlock()
-			switch {
-			case errors.As(err, &objects.ErrMultiTenancy{}):
+			switch err.(type) {
+			case objects.ErrMultiTenancy:
 				return nil, objects.NewErrMultiTenancy(fmt.Errorf("search index %s: %w", index.ID(), err))
 			default:
 				return nil, fmt.Errorf("search index %s: %w", index.ID(), err)
@@ -226,8 +225,8 @@ func (db *DB) anyExists(ctx context.Context, id strfmt.UUID,
 	for _, index := range db.indices {
 		ok, err := index.exists(ctx, id, repl, "")
 		if err != nil {
-			switch {
-			case errors.As(err, &objects.ErrMultiTenancy{}):
+			switch err.(type) {
+			case objects.ErrMultiTenancy:
 				return false, objects.NewErrMultiTenancy(fmt.Errorf("search index %s: %w", index.ID(), err))
 			default:
 				return false, fmt.Errorf("search index %s: %w", index.ID(), err)
diff --git a/adapters/repos/db/index.go b/adapters/repos/db/index.go
index 822af1242c..a9478eb06c 100644
--- a/adapters/repos/db/index.go
+++ b/adapters/repos/db/index.go
@@ -24,29 +24,31 @@ import (
 	"sync/atomic"
 	"time"
 
+	"github.com/weaviate/weaviate/entities/dto"
+	"github.com/weaviate/weaviate/entities/modulecapabilities"
+
+	"github.com/weaviate/weaviate/adapters/repos/db/lsmkv"
+	"github.com/weaviate/weaviate/adapters/repos/db/queue"
+
+	"github.com/pkg/errors"
+
 	"github.com/go-openapi/strfmt"
 	"github.com/google/uuid"
-	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/adapters/repos/db/aggregator"
 	"github.com/weaviate/weaviate/adapters/repos/db/helpers"
 	"github.com/weaviate/weaviate/adapters/repos/db/indexcheckpoint"
 	"github.com/weaviate/weaviate/adapters/repos/db/inverted"
 	"github.com/weaviate/weaviate/adapters/repos/db/inverted/stopwords"
-	"github.com/weaviate/weaviate/adapters/repos/db/lsmkv"
-	"github.com/weaviate/weaviate/adapters/repos/db/queue"
 	"github.com/weaviate/weaviate/adapters/repos/db/sorter"
 	"github.com/weaviate/weaviate/adapters/repos/db/vector/hnsw"
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/aggregation"
 	"github.com/weaviate/weaviate/entities/autocut"
-	"github.com/weaviate/weaviate/entities/dto"
 	"github.com/weaviate/weaviate/entities/errorcompounder"
 	enterrors "github.com/weaviate/weaviate/entities/errors"
 	"github.com/weaviate/weaviate/entities/filters"
 	"github.com/weaviate/weaviate/entities/models"
-	"github.com/weaviate/weaviate/entities/modulecapabilities"
 	"github.com/weaviate/weaviate/entities/multi"
 	"github.com/weaviate/weaviate/entities/schema"
 	schemaConfig "github.com/weaviate/weaviate/entities/schema/config"
@@ -56,7 +58,7 @@ import (
 	"github.com/weaviate/weaviate/entities/storagestate"
 	"github.com/weaviate/weaviate/entities/storobj"
 	esync "github.com/weaviate/weaviate/entities/sync"
-	authzerrors "github.com/weaviate/weaviate/usecases/auth/authorization/errors"
+	authErrs "github.com/weaviate/weaviate/usecases/auth/authorization/errors"
 	"github.com/weaviate/weaviate/usecases/config"
 	"github.com/weaviate/weaviate/usecases/memwatch"
 	"github.com/weaviate/weaviate/usecases/modules"
@@ -666,10 +668,10 @@ func (i *Index) putObject(ctx context.Context, object *storobj.Object,
 
 	shardName, err := i.determineObjectShard(ctx, object.ID(), object.Object.Tenant)
 	if err != nil {
-		switch {
-		case errors.As(err, &objects.ErrMultiTenancy{}):
+		switch err.(type) {
+		case objects.ErrMultiTenancy:
 			return objects.NewErrMultiTenancy(fmt.Errorf("determine shard: %w", err))
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case authErrs.Forbidden:
 			return fmt.Errorf("determine shard: %w", err)
 		default:
 			return objects.NewErrInvalidUserInput("determine shard: %v", err)
@@ -1054,10 +1056,12 @@ func (i *Index) objectByID(ctx context.Context, id strfmt.UUID,
 
 	shardName, err := i.determineObjectShard(ctx, id, tenant)
 	if err != nil {
+		var errMultiTenancy objects.ErrMultiTenancy
+		var forbidden authErrs.Forbidden
 		switch {
-		case errors.As(err, &objects.ErrMultiTenancy{}):
+		case errors.As(err, &errMultiTenancy):
 			return nil, objects.NewErrMultiTenancy(fmt.Errorf("determine shard: %w", err))
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &forbidden):
 			return nil, fmt.Errorf("determine shard: %w", err)
 		default:
 			return nil, objects.NewErrInvalidUserInput("determine shard: %v", err)
@@ -1147,10 +1151,10 @@ func (i *Index) multiObjectByID(ctx context.Context,
 	for pos, id := range query {
 		shardName, err := i.determineObjectShard(ctx, strfmt.UUID(id.ID), tenant)
 		if err != nil {
-			switch {
-			case errors.As(err, &objects.ErrMultiTenancy{}):
+			switch err.(type) {
+			case objects.ErrMultiTenancy:
 				return nil, objects.NewErrMultiTenancy(fmt.Errorf("determine shard: %w", err))
-			case errors.As(err, &authzerrors.Forbidden{}):
+			case authErrs.Forbidden:
 				return nil, fmt.Errorf("determine shard: %w", err)
 			default:
 				return nil, objects.NewErrInvalidUserInput("determine shard: %v", err)
@@ -1223,10 +1227,12 @@ func (i *Index) exists(ctx context.Context, id strfmt.UUID,
 
 	shardName, err := i.determineObjectShard(ctx, id, tenant)
 	if err != nil {
+		var errMultiTenancy objects.ErrMultiTenancy
+		var forbidden authErrs.Forbidden
 		switch {
-		case errors.As(err, &objects.ErrMultiTenancy{}):
+		case errors.As(err, &errMultiTenancy):
 			return false, objects.NewErrMultiTenancy(fmt.Errorf("determine shard: %w", err))
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &forbidden):
 			return false, fmt.Errorf("determine shard: %w", err)
 		default:
 			return false, objects.NewErrInvalidUserInput("determine shard: %v", err)
@@ -1792,10 +1798,12 @@ func (i *Index) deleteObject(ctx context.Context, id strfmt.UUID,
 
 	shardName, err := i.determineObjectShard(ctx, id, tenant)
 	if err != nil {
+		var errMultiTenancy objects.ErrMultiTenancy
+		var forbidden authErrs.Forbidden
 		switch {
-		case errors.As(err, &objects.ErrMultiTenancy{}):
+		case errors.As(err, &errMultiTenancy):
 			return objects.NewErrMultiTenancy(fmt.Errorf("determine shard: %w", err))
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case errors.As(err, &forbidden):
 			return fmt.Errorf("determine shard: %w", err)
 		default:
 			return objects.NewErrInvalidUserInput("determine shard: %v", err)
@@ -1969,10 +1977,10 @@ func (i *Index) mergeObject(ctx context.Context, merge objects.MergeDocument,
 
 	shardName, err := i.determineObjectShard(ctx, merge.ID, tenant)
 	if err != nil {
-		switch {
-		case errors.As(err, &objects.ErrMultiTenancy{}):
+		switch err.(type) {
+		case objects.ErrMultiTenancy:
 			return objects.NewErrMultiTenancy(fmt.Errorf("determine shard: %w", err))
-		case errors.As(err, &authzerrors.Forbidden{}):
+		case authErrs.Forbidden:
 			return fmt.Errorf("determine shard: %w", err)
 		default:
 			return objects.NewErrInvalidUserInput("determine shard: %v", err)
diff --git a/adapters/repos/db/inverted_reindexer_specified_index.go b/adapters/repos/db/inverted_reindexer_specified_index.go
index d1b86822c7..1473a356b3 100644
--- a/adapters/repos/db/inverted_reindexer_specified_index.go
+++ b/adapters/repos/db/inverted_reindexer_specified_index.go
@@ -143,7 +143,7 @@ func (t *ShardInvertedReindexTask_SpecifiedIndex) ObjectsIterator(shard ShardLik
 		for k, v := cursor.First(); k != nil; k, v = cursor.Next() {
 			obj, err := storobj.FromBinaryOptional(v, additional.Properties{}, propsExtraction)
 			if err != nil {
-				return fmt.Errorf("cannot unmarshal object %d, %w", i, err)
+				return fmt.Errorf("cannot unmarshal object %d, %v", i, err)
 			}
 			if err := fn(obj); err != nil {
 				return fmt.Errorf("callback on object '%d' failed: %w", obj.DocID, err)
diff --git a/adapters/repos/db/lsmkv/bucket.go b/adapters/repos/db/lsmkv/bucket.go
index 71741a170c..896331d8b7 100644
--- a/adapters/repos/db/lsmkv/bucket.go
+++ b/adapters/repos/db/lsmkv/bucket.go
@@ -27,7 +27,6 @@ import (
 	"github.com/pkg/errors"
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/sroar"
 	"github.com/weaviate/weaviate/adapters/repos/db/helpers"
 	"github.com/weaviate/weaviate/adapters/repos/db/inverted/terms"
@@ -328,7 +327,7 @@ func (b *Bucket) iterateObjectsCursor(ctx context.Context, cursor *CursorReplace
 	for k, v := cursor.First(); k != nil; k, v = cursor.Next() {
 		obj, err := storobj.FromBinary(v)
 		if err != nil {
-			return fmt.Errorf("cannot unmarshal object %d, %w", i, err)
+			return fmt.Errorf("cannot unmarshal object %d, %v", i, err)
 		}
 		if err := f(obj); err != nil {
 			return fmt.Errorf("callback on object '%d' failed: %w", obj.DocID, err)
@@ -446,7 +445,7 @@ func (b *Bucket) GetErrDeleted(key []byte) ([]byte, error) {
 		return nil, err
 	}
 
-	if !errors.Is(err, lsmkv.NotFound) {
+	if err != lsmkv.NotFound {
 		panic(fmt.Sprintf("unsupported error in bucket.Get: %v\n", err))
 	}
 
@@ -463,7 +462,7 @@ func (b *Bucket) GetErrDeleted(key []byte) ([]byte, error) {
 			return nil, err
 		}
 
-		if !errors.Is(err, lsmkv.NotFound) {
+		if err != lsmkv.NotFound {
 			panic("unsupported error in bucket.Get")
 		}
 	}
@@ -690,8 +689,8 @@ func (b *Bucket) WasDeleted(key []byte) (bool, time.Time, error) {
 		return false, time.Time{}, nil
 	}
 	if errors.Is(err, lsmkv.Deleted) {
-		var errDeleted lsmkv.ErrDeleted
-		if errors.As(err, &errDeleted) {
+		errDeleted, ok := err.(lsmkv.ErrDeleted)
+		if ok {
 			return true, errDeleted.DeletionTime(), nil
 		} else {
 			return true, time.Time{}, nil
@@ -709,8 +708,8 @@ func (b *Bucket) WasDeleted(key []byte) (bool, time.Time, error) {
 			return false, time.Time{}, nil
 		}
 		if errors.Is(err, lsmkv.Deleted) {
-			var errDeleted lsmkv.ErrDeleted
-			if errors.As(err, &errDeleted) {
+			errDeleted, ok := err.(lsmkv.ErrDeleted)
+			if ok {
 				return true, errDeleted.DeletionTime(), nil
 			} else {
 				return true, time.Time{}, nil
@@ -728,8 +727,8 @@ func (b *Bucket) WasDeleted(key []byte) (bool, time.Time, error) {
 		return false, time.Time{}, nil
 	}
 	if errors.Is(err, lsmkv.Deleted) {
-		var errDeleted lsmkv.ErrDeleted
-		if errors.As(err, &errDeleted) {
+		errDeleted, ok := err.(lsmkv.ErrDeleted)
+		if ok {
 			return true, errDeleted.DeletionTime(), nil
 		} else {
 			return true, time.Time{}, nil
diff --git a/adapters/repos/db/lsmkv/segment.go b/adapters/repos/db/lsmkv/segment.go
index a4bcd4879f..6a305c4a4d 100644
--- a/adapters/repos/db/lsmkv/segment.go
+++ b/adapters/repos/db/lsmkv/segment.go
@@ -222,7 +222,7 @@ func (s *segment) close() error {
 	}
 
 	if munmapErr != nil || fileCloseErr != nil {
-		return fmt.Errorf("close segment: munmap: %w, close contents file: %w", munmapErr, fileCloseErr)
+		return fmt.Errorf("close segment: munmap: %v, close contents file: %w", munmapErr, fileCloseErr)
 	}
 
 	return nil
diff --git a/adapters/repos/db/nodes.go b/adapters/repos/db/nodes.go
index 9a64fc30f0..726f7d3c0a 100644
--- a/adapters/repos/db/nodes.go
+++ b/adapters/repos/db/nodes.go
@@ -17,7 +17,6 @@ import (
 	"sort"
 
 	"github.com/pkg/errors"
-
 	enterrors "github.com/weaviate/weaviate/entities/errors"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/entities/schema"
@@ -62,17 +61,16 @@ func (db *DB) getNodeStatus(ctx context.Context, nodeName string, className, out
 	}
 	status, err := db.remoteNode.GetNodeStatus(ctx, nodeName, className, output)
 	if err != nil {
-		var errSendHttpRequest *enterrors.ErrSendHttpRequest
-		switch {
-		case errors.As(err, &errSendHttpRequest):
-			if errors.Is(errSendHttpRequest.Unwrap(), context.DeadlineExceeded) {
+		switch typed := err.(type) {
+		case enterrors.ErrSendHttpRequest:
+			if errors.Is(typed.Unwrap(), context.DeadlineExceeded) {
 				nodeTimeout := models.NodeStatusStatusTIMEOUT
 				return &models.NodeStatus{Name: nodeName, Status: &nodeTimeout}, nil
 			}
 
 			nodeUnavailable := models.NodeStatusStatusUNAVAILABLE
 			return &models.NodeStatus{Name: nodeName, Status: &nodeUnavailable}, nil
-		case errors.As(err, &enterrors.ErrOpenHttpRequest{}):
+		case enterrors.ErrOpenHttpRequest:
 			nodeUnavailable := models.NodeStatusStatusUNAVAILABLE
 			return &models.NodeStatus{Name: nodeName, Status: &nodeUnavailable}, nil
 		default:
@@ -307,17 +305,16 @@ func (db *DB) getNodeStatistics(ctx context.Context, nodeName string) (*models.S
 	}
 	statistics, err := db.remoteNode.GetStatistics(ctx, nodeName)
 	if err != nil {
-		var errSendHttpRequest *enterrors.ErrSendHttpRequest
-		switch {
-		case errors.As(err, &errSendHttpRequest):
-			if errors.Is(errSendHttpRequest.Unwrap(), context.DeadlineExceeded) {
+		switch typed := err.(type) {
+		case enterrors.ErrSendHttpRequest:
+			if errors.Is(typed.Unwrap(), context.DeadlineExceeded) {
 				nodeTimeout := models.StatisticsStatusTIMEOUT
 				return &models.Statistics{Name: nodeName, Status: &nodeTimeout}, nil
 			}
 
 			nodeUnavailable := models.StatisticsStatusUNAVAILABLE
 			return &models.Statistics{Name: nodeName, Status: &nodeUnavailable}, nil
-		case errors.As(err, &enterrors.ErrOpenHttpRequest{}):
+		case enterrors.ErrOpenHttpRequest:
 			nodeUnavailable := models.StatisticsStatusUNAVAILABLE
 			return &models.Statistics{Name: nodeName, Status: &nodeUnavailable}, nil
 		default:
diff --git a/adapters/repos/db/refcache/cacher.go b/adapters/repos/db/refcache/cacher.go
index e72309f143..951adead92 100644
--- a/adapters/repos/db/refcache/cacher.go
+++ b/adapters/repos/db/refcache/cacher.go
@@ -82,13 +82,13 @@ func (c *Cacher) Build(ctx context.Context, objects []search.Result,
 	c.groupByProps = groupByProperties
 	err := c.findJobsFromResponse(objects, properties)
 	if err != nil {
-		return fmt.Errorf("build request cache: %w", err)
+		return fmt.Errorf("build request cache: %v", err)
 	}
 
 	c.dedupJobList()
 	err = c.fetchJobs(ctx)
 	if err != nil {
-		return fmt.Errorf("build request cache: %w", err)
+		return fmt.Errorf("build request cache: %v", err)
 	}
 
 	return nil
diff --git a/adapters/repos/db/replication.go b/adapters/repos/db/replication.go
index 612e94d272..c27641a5c9 100644
--- a/adapters/repos/db/replication.go
+++ b/adapters/repos/db/replication.go
@@ -22,7 +22,6 @@ import (
 
 	"github.com/go-openapi/strfmt"
 	"github.com/pkg/errors"
-
 	"github.com/weaviate/weaviate/entities/additional"
 	enterrors "github.com/weaviate/weaviate/entities/errors"
 	"github.com/weaviate/weaviate/entities/lsmkv"
@@ -376,8 +375,8 @@ func (idx *Index) OverwriteObjects(ctx context.Context,
 			currUpdateTime = localObj.LastUpdateTimeUnix()
 		} else if errors.Is(err, lsmkv.Deleted) {
 			locallyDeleted = true
-			var errDeleted lsmkv.ErrDeleted
-			if errors.As(err, &errDeleted) {
+			errDeleted, ok := err.(lsmkv.ErrDeleted)
+			if ok {
 				currUpdateTime = errDeleted.DeletionTime().UnixMilli()
 			} // otherwise an unknown deletion time
 		} else if !errors.Is(err, lsmkv.NotFound) {
diff --git a/adapters/repos/db/search.go b/adapters/repos/db/search.go
index 967608c3f9..70adae9d74 100644
--- a/adapters/repos/db/search.go
+++ b/adapters/repos/db/search.go
@@ -18,13 +18,13 @@ import (
 	"strings"
 	"sync"
 
-	"github.com/pkg/errors"
+	enterrors "github.com/weaviate/weaviate/entities/errors"
 
+	"github.com/pkg/errors"
 	"github.com/weaviate/weaviate/adapters/repos/db/refcache"
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/aggregation"
 	"github.com/weaviate/weaviate/entities/dto"
-	enterrors "github.com/weaviate/weaviate/entities/errors"
 	"github.com/weaviate/weaviate/entities/filters"
 	"github.com/weaviate/weaviate/entities/schema"
 	"github.com/weaviate/weaviate/entities/search"
@@ -229,8 +229,8 @@ func (db *DB) Query(ctx context.Context, q *objects.QueryInput) (search.Results,
 	res, _, err := idx.objectSearch(ctx, totalLimit, q.Filters,
 		nil, q.Sort, q.Cursor, q.Additional, nil, q.Tenant, 0, nil)
 	if err != nil {
-		switch {
-		case errors.As(err, &objects.ErrMultiTenancy{}):
+		switch err.(type) {
+		case objects.ErrMultiTenancy:
 			return nil, &objects.Error{Msg: "search index " + idx.ID(), Code: objects.StatusUnprocessableEntity, Err: err}
 		default:
 			return nil, &objects.Error{Msg: "search index " + idx.ID(), Code: objects.StatusInternalServerError, Err: err}
diff --git a/adapters/repos/db/shard_backup.go b/adapters/repos/db/shard_backup.go
index 5e74b47bdf..23bd3a0802 100644
--- a/adapters/repos/db/shard_backup.go
+++ b/adapters/repos/db/shard_backup.go
@@ -27,7 +27,7 @@ func (s *Shard) HaltForTransfer(ctx context.Context) (err error) {
 		if err != nil {
 			err = fmt.Errorf("pause compaction: %w", err)
 			if err2 := s.resumeMaintenanceCycles(ctx); err2 != nil {
-				err = fmt.Errorf("%w: resume maintenance: %w", err, err2)
+				err = fmt.Errorf("%w: resume maintenance: %v", err, err2)
 			}
 		}
 	}()
diff --git a/adapters/repos/db/shard_hashbeater.go b/adapters/repos/db/shard_hashbeater.go
index d726fa6548..276e951374 100644
--- a/adapters/repos/db/shard_hashbeater.go
+++ b/adapters/repos/db/shard_hashbeater.go
@@ -297,7 +297,7 @@ func (s *Shard) hashBeat() (stats hashBeatStats, err error) {
 				propagationLimitPerHashbeatIteration-objectsPropagated,
 			)
 			if err != nil {
-				propagationErr = fmt.Errorf("propagating local objects: %w", err)
+				propagationErr = fmt.Errorf("propagating local objects: %v", err)
 				break
 			}
 
diff --git a/adapters/repos/db/shard_read.go b/adapters/repos/db/shard_read.go
index 1846e82c49..7841b54252 100644
--- a/adapters/repos/db/shard_read.go
+++ b/adapters/repos/db/shard_read.go
@@ -154,12 +154,12 @@ func (s *Shard) ObjectDigestsByTokenRange(ctx context.Context,
 	for k, v := cursor.Seek(initialTokenBytes[:]); n < limit && k != nil && bytes.Compare(k, finalTokenBytes[:]) < 1; k, v = cursor.Next() {
 		obj, err := storobj.FromBinary(v)
 		if err != nil {
-			return objs, lastTokenRead, fmt.Errorf("cannot unmarshal object: %w", err)
+			return objs, lastTokenRead, fmt.Errorf("cannot unmarshal object: %v", err)
 		}
 
 		uuidBytes, err := uuid.MustParse(obj.ID().String()).MarshalBinary()
 		if err != nil {
-			return objs, lastTokenRead, fmt.Errorf("cannot unmarshal object: %w", err)
+			return objs, lastTokenRead, fmt.Errorf("cannot unmarshal object: %v", err)
 		}
 
 		replicaObj := replica.RepairResponse{
diff --git a/adapters/repos/db/vector/flat/index.go b/adapters/repos/db/vector/flat/index.go
index ab61f3c52c..7065fd0004 100644
--- a/adapters/repos/db/vector/flat/index.go
+++ b/adapters/repos/db/vector/flat/index.go
@@ -27,7 +27,6 @@ import (
 
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/adapters/repos/db/helpers"
 	"github.com/weaviate/weaviate/adapters/repos/db/lsmkv"
 	"github.com/weaviate/weaviate/adapters/repos/db/priorityqueue"
@@ -853,7 +852,7 @@ func (index *flat) ContainsNode(id uint64) bool {
 	idBytes := make([]byte, 8)
 	binary.BigEndian.PutUint64(idBytes, id)
 	v, err := index.store.Bucket(bucketName).Get(idBytes)
-	if v == nil || errors.Is(err, entlsmkv.NotFound) {
+	if v == nil || err == entlsmkv.NotFound {
 		return false
 	}
 
diff --git a/cluster/schema/manager.go b/cluster/schema/manager.go
index 0fda9b1db0..06b13e3ff3 100644
--- a/cluster/schema/manager.go
+++ b/cluster/schema/manager.go
@@ -392,7 +392,7 @@ func (op applyOp) validate() error {
 // apply does apply commands from RAFT to schema 1st and then db
 func (s *SchemaManager) apply(op applyOp) error {
 	if err := op.validate(); err != nil {
-		return fmt.Errorf("could not validate raft apply op: %w", err)
+		return fmt.Errorf("could not validate raft apply op: %s", err)
 	}
 
 	// schema applied 1st to make sure any validation happen before applying it to db
diff --git a/cluster/schema/snapshot.go b/cluster/schema/snapshot.go
index b1f56f8937..5c1abbb8a5 100644
--- a/cluster/schema/snapshot.go
+++ b/cluster/schema/snapshot.go
@@ -29,7 +29,7 @@ type snapshot struct {
 func (s *schema) Restore(r io.Reader, parser Parser) error {
 	snap := snapshot{}
 	if err := json.NewDecoder(r).Decode(&snap); err != nil {
-		return fmt.Errorf("restore snapshot: decode json: %w", err)
+		return fmt.Errorf("restore snapshot: decode json: %v", err)
 	}
 	for _, cls := range snap.Classes {
 		if err := parser.ParseClass(&cls.Class); err != nil { // should not fail
diff --git a/cluster/store_apply.go b/cluster/store_apply.go
index 778c0edd29..72ff043369 100644
--- a/cluster/store_apply.go
+++ b/cluster/store_apply.go
@@ -18,12 +18,11 @@ import (
 
 	"github.com/hashicorp/raft"
 	"github.com/sirupsen/logrus"
-	"google.golang.org/protobuf/proto"
-	gproto "google.golang.org/protobuf/proto"
-
 	"github.com/weaviate/weaviate/cluster/proto/api"
 	"github.com/weaviate/weaviate/cluster/types"
 	enterrors "github.com/weaviate/weaviate/entities/errors"
+	"google.golang.org/protobuf/proto"
+	gproto "google.golang.org/protobuf/proto"
 )
 
 func (st *Store) Execute(req *api.ApplyRequest) (uint64, error) {
diff --git a/entities/schema/crossref/crossref.go b/entities/schema/crossref/crossref.go
index b78aeef386..8c829f65c3 100644
--- a/entities/schema/crossref/crossref.go
+++ b/entities/schema/crossref/crossref.go
@@ -43,7 +43,7 @@ type Ref struct {
 func Parse(uriString string) (*Ref, error) {
 	uri, err := url.Parse(uriString)
 	if err != nil || uri.Path == "" {
-		return nil, fmt.Errorf("invalid cref URI: %w", err)
+		return nil, fmt.Errorf("invalid cref URI: %s", err)
 	}
 
 	segments := strings.Split(uri.Path, "/")
diff --git a/entities/schema/crossref/crossref_source.go b/entities/schema/crossref/crossref_source.go
index 64573701bf..377eb921ee 100644
--- a/entities/schema/crossref/crossref_source.go
+++ b/entities/schema/crossref/crossref_source.go
@@ -53,7 +53,7 @@ func NewSource(className schema.ClassName,
 func ParseSource(uriString string) (*RefSource, error) {
 	uri, err := url.Parse(uriString)
 	if err != nil {
-		return nil, fmt.Errorf("invalid cref URI: %w", err)
+		return nil, fmt.Errorf("invalid cref URI: %s", err)
 	}
 
 	pathSegments := strings.Split(uri.Path, "/")
diff --git a/modules/backup-gcs/client.go b/modules/backup-gcs/client.go
index 638a11b795..1deb7a8461 100644
--- a/modules/backup-gcs/client.go
+++ b/modules/backup-gcs/client.go
@@ -24,13 +24,12 @@ import (
 	"cloud.google.com/go/storage"
 	"github.com/googleapis/gax-go/v2"
 	"github.com/pkg/errors"
-	"golang.org/x/oauth2/google"
-	"google.golang.org/api/iterator"
-	"google.golang.org/api/option"
-
 	"github.com/weaviate/weaviate/entities/backup"
 	ubak "github.com/weaviate/weaviate/usecases/backup"
 	"github.com/weaviate/weaviate/usecases/monitoring"
+	"golang.org/x/oauth2/google"
+	"google.golang.org/api/iterator"
+	"google.golang.org/api/option"
 )
 
 type gcsClient struct {
@@ -351,7 +350,7 @@ func (g *gcsClient) Read(ctx context.Context, backupID, key, overrideBucket, ove
 	path := g.makeObjectName(overridePath, []string{backupID, key})
 	rc, err := bucket.Object(path).NewReader(ctx)
 	if err != nil {
-		err = fmt.Errorf("create reader %s: %w", path, err)
+		err = fmt.Errorf("create reader %s: %v", path, err)
 		if errors.Is(err, storage.ErrObjectNotExist) {
 			err = backup.NewErrNotFound(err)
 		}
diff --git a/modules/backup-s3/client.go b/modules/backup-s3/client.go
index d65d8f867c..79c371072d 100644
--- a/modules/backup-s3/client.go
+++ b/modules/backup-s3/client.go
@@ -26,7 +26,6 @@ import (
 	"github.com/minio/minio-go/v7/pkg/credentials"
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/entities/backup"
 	ubak "github.com/weaviate/weaviate/usecases/backup"
 	"github.com/weaviate/weaviate/usecases/modulecomponents"
@@ -162,8 +161,7 @@ func (s *s3Client) GetObject(ctx context.Context, backupID, key, overrideBucket,
 
 	contents, err := io.ReadAll(obj)
 	if err != nil {
-		var s3Err minio.ErrorResponse
-		if errors.As(err, &s3Err) && s3Err.StatusCode == http.StatusNotFound {
+		if s3Err, ok := err.(minio.ErrorResponse); ok && s3Err.StatusCode == http.StatusNotFound {
 			return nil, backup.NewErrNotFound(errors.Wrapf(err, "get object contents from %s:%s not found %s", bucket, remotePath, remotePath))
 		}
 		return nil, backup.NewErrInternal(errors.Wrapf(err, "get object contents from %s:%s %s", bucket, remotePath, remotePath))
@@ -319,8 +317,7 @@ func (s *s3Client) Read(ctx context.Context, backupID, key, overrideBucket, over
 	read, err := io.Copy(w, obj)
 	if err != nil {
 		err = fmt.Errorf("get object %q: %w", remotePath, err)
-		var s3Err minio.ErrorResponse
-		if errors.As(err, &s3Err) && s3Err.StatusCode == http.StatusNotFound {
+		if s3Err, ok := err.(minio.ErrorResponse); ok && s3Err.StatusCode == http.StatusNotFound {
 			err = backup.NewErrNotFound(err)
 		}
 		return 0, err
diff --git a/modules/text2vec-contextionary/additional/sempath/builder.go b/modules/text2vec-contextionary/additional/sempath/builder.go
index e55f5e3a35..290d615709 100644
--- a/modules/text2vec-contextionary/additional/sempath/builder.go
+++ b/modules/text2vec-contextionary/additional/sempath/builder.go
@@ -84,7 +84,7 @@ func (pb *PathBuilder) CalculatePath(in []search.Result, params *Params) ([]sear
 	for i, obj := range in {
 		path, err := pb.calculatePathPerObject(obj, in, params, searchNeighbors)
 		if err != nil {
-			return nil, fmt.Errorf("object %d: %w", i, err)
+			return nil, fmt.Errorf("object %d: %v", i, err)
 		}
 
 		if in[i].AdditionalProperties == nil {
diff --git a/modules/text2vec-contextionary/classification/classifier_prepare_contextual.go b/modules/text2vec-contextionary/classification/classifier_prepare_contextual.go
index 038c72a0e8..8edd5c26b8 100644
--- a/modules/text2vec-contextionary/classification/classifier_prepare_contextual.go
+++ b/modules/text2vec-contextionary/classification/classifier_prepare_contextual.go
@@ -113,12 +113,12 @@ func (p *contextualPreparer) findTargetsForProps() (map[string]search.Results, e
 	for _, targetProp := range p.params.ClassifyProperties {
 		class, err := p.classAndKindOfTarget(targetProp)
 		if err != nil {
-			return nil, fmt.Errorf("target prop '%s': find target class: %w", targetProp, err)
+			return nil, fmt.Errorf("target prop '%s': find target class: %v", targetProp, err)
 		}
 
 		targets, err := p.findTargets(class)
 		if err != nil {
-			return nil, fmt.Errorf("target prop '%s': find targets: %w", targetProp, err)
+			return nil, fmt.Errorf("target prop '%s': find targets: %v", targetProp, err)
 		}
 
 		targetsMap[targetProp] = targets
@@ -139,7 +139,7 @@ func (p *contextualPreparer) findTargets(class schema.ClassName) (search.Results
 		Properties: []string{"id"},
 	})
 	if err != nil {
-		return nil, fmt.Errorf("search closest target: %w", err)
+		return nil, fmt.Errorf("search closest target: %v", err)
 	}
 
 	if len(res) == 0 {
@@ -162,7 +162,7 @@ func (p *contextualPreparer) classAndKindOfTarget(propName string) (schema.Class
 
 	dataType, err := schema.FindPropertyDataTypeWithRefs(p.getClass, prop.DataType, false, "")
 	if err != nil {
-		return "", fmt.Errorf("extract dataType of prop '%s': %w", propName, err)
+		return "", fmt.Errorf("extract dataType of prop '%s': %v", propName, err)
 	}
 
 	// we have passed validation, so it is safe to assume that this is a ref prop
diff --git a/modules/text2vec-contextionary/classification/classifier_run_contextual.go b/modules/text2vec-contextionary/classification/classifier_run_contextual.go
index 75969355ef..ca6600a647 100644
--- a/modules/text2vec-contextionary/classification/classifier_run_contextual.go
+++ b/modules/text2vec-contextionary/classification/classifier_run_contextual.go
@@ -81,7 +81,7 @@ func (c *Classifier) makeClassifyItemContextual(preparedContext contextualPrepar
 
 		err := run.do()
 		if err != nil {
-			return fmt.Errorf("text2vec-contextionary-contextual: %w", err)
+			return fmt.Errorf("text2vec-contextionary-contextual: %v", err)
 		}
 
 		return nil
@@ -93,7 +93,7 @@ func (c *contextualItemClassifier) do() error {
 	for _, propName := range c.params.ClassifyProperties {
 		current, err := c.property(propName)
 		if err != nil {
-			return fmt.Errorf("prop '%s': %w", propName, err)
+			return fmt.Errorf("prop '%s': %v", propName, err)
 		}
 
 		// append list of actually classified (can differ from scope!) properties,
@@ -104,7 +104,7 @@ func (c *contextualItemClassifier) do() error {
 	c.classifier.extendItemWithObjectMeta(&c.item, c.params, classified)
 	err := c.writer.Store(c.item)
 	if err != nil {
-		return fmt.Errorf("store %s/%s: %w", c.item.ClassName, c.item.ID, err)
+		return fmt.Errorf("store %s/%s: %v", c.item.ClassName, c.item.ID, err)
 	}
 
 	return nil
@@ -142,31 +142,31 @@ func (c *contextualItemClassifier) property(propName string) (string, error) {
 
 	vectors, err := c.vectorizer.MultiVectorForWord(ctx, words)
 	if err != nil {
-		return "", fmt.Errorf("vectorize individual words: %w", err)
+		return "", fmt.Errorf("vectorize individual words: %v", err)
 	}
 
 	scoredWords, err := c.scoreWords(words, vectors, propName)
 	if err != nil {
-		return "", fmt.Errorf("score words: %w", err)
+		return "", fmt.Errorf("score words: %v", err)
 	}
 
 	c.rankedWords[propName] = c.rankAndDedup(scoredWords)
 
 	corpus, boosts, err := c.buildBoostedCorpus(propName)
 	if err != nil {
-		return "", fmt.Errorf("build corpus: %w", err)
+		return "", fmt.Errorf("build corpus: %v", err)
 	}
 
 	ctx, cancel = contextWithTimeout(10 * time.Second)
 	defer cancel()
 	vector, err := c.vectorizer.VectorOnlyForCorpi(ctx, []string{corpus}, boosts)
 	if err != nil {
-		return "", fmt.Errorf("vectorize corpus: %w", err)
+		return "", fmt.Errorf("vectorize corpus: %v", err)
 	}
 
 	target, distance, err := c.findClosestTarget(vector, propName)
 	if err != nil {
-		return "", fmt.Errorf("find closest target: %w", err)
+		return "", fmt.Errorf("find closest target: %v", err)
 	}
 
 	targetBeacon := crossref.New("localhost", target.ClassName, target.ID).String()
@@ -189,7 +189,7 @@ func (c *contextualItemClassifier) findClosestTarget(query []float32, targetProp
 	for _, item := range c.context.targets[targetProp] {
 		dist, err := cosineDist(query, item.Vector)
 		if err != nil {
-			return nil, -1, fmt.Errorf("calculate distance: %w", err)
+			return nil, -1, fmt.Errorf("calculate distance: %v", err)
 		}
 
 		if dist < minimum {
@@ -322,7 +322,7 @@ func (c *contextualItemClassifier) scoreWords(words []string, vectors [][]float3
 		word := strings.ToLower(words[i])
 		sw, err := c.scoreWord(word, vectors[i], targetProp)
 		if err != nil {
-			return nil, fmt.Errorf("score word '%s': %w", word, err)
+			return nil, fmt.Errorf("score word '%s': %v", word, err)
 		}
 
 		// accept nil-entries for now, they will be removed in ranking/deduping
@@ -350,7 +350,7 @@ func (c *contextualItemClassifier) scoreWord(word string, vector []float32,
 	for _, target := range targets {
 		dist, err := cosineDist(vector, target.Vector)
 		if err != nil {
-			return nil, fmt.Errorf("calculate cosine distance: %w", err)
+			return nil, fmt.Errorf("calculate cosine distance: %v", err)
 		}
 
 		all = append(all, dist)
diff --git a/modules/text2vec-contextionary/client/contextionary.go b/modules/text2vec-contextionary/client/contextionary.go
index 7ab6f152da..cbcf65e625 100644
--- a/modules/text2vec-contextionary/client/contextionary.go
+++ b/modules/text2vec-contextionary/client/contextionary.go
@@ -44,7 +44,7 @@ func NewClient(uri string, logger logrus.FieldLogger) (*Client, error) {
 		grpc.WithTransportCredentials(insecure.NewCredentials()),
 		grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(1024*1024*48)))
 	if err != nil {
-		return nil, fmt.Errorf("couldn't connect to remote contextionary gRPC server: %w", err)
+		return nil, fmt.Errorf("couldn't connect to remote contextionary gRPC server: %s", err)
 	}
 
 	client := pb.NewContextionaryClient(conn)
@@ -155,7 +155,7 @@ func (c *Client) VectorForWord(ctx context.Context, word string) ([]float32, err
 	res, err := c.grpcClient.VectorForWord(ctx, &pb.Word{Word: word})
 	if err != nil {
 		logConnectionRefused(c.logger, err)
-		return nil, fmt.Errorf("could not get vector from remote: %w", err)
+		return nil, fmt.Errorf("could not get vector from remote: %v", err)
 	}
 	v, _, _ := vectorFromProto(res)
 	return v, nil
@@ -263,7 +263,7 @@ func (c *Client) VectorForCorpi(ctx context.Context, corpi []string, overridesMa
 		}
 		st, ok := status.FromError(err)
 		if !ok || st.Code() != codes.InvalidArgument {
-			return nil, nil, fmt.Errorf("could not get vector from remote: %w", err)
+			return nil, nil, fmt.Errorf("could not get vector from remote: %v", err)
 		}
 
 		return nil, nil, vectorizer.NewErrNoUsableWordsf("%s", st.Message())
@@ -285,7 +285,7 @@ func (c *Client) NearestWordsByVector(ctx context.Context, vector []float32, n i
 	})
 	if err != nil {
 		logConnectionRefused(c.logger, err)
-		return nil, nil, fmt.Errorf("could not get nearest words by vector: %w", err)
+		return nil, nil, fmt.Errorf("could not get nearest words by vector: %v", err)
 	}
 
 	return res.Words, res.Distances, nil
diff --git a/modules/text2vec-contextionary/vectorizer/inspector.go b/modules/text2vec-contextionary/vectorizer/inspector.go
index 0d10fe50e3..af40bf7ad4 100644
--- a/modules/text2vec-contextionary/vectorizer/inspector.go
+++ b/modules/text2vec-contextionary/vectorizer/inspector.go
@@ -139,7 +139,7 @@ func (i *Inspector) individualWords(ctx context.Context,
 	for _, word := range wordArray {
 		iw, err := i.individualWord(ctx, word)
 		if err != nil {
-			return nil, fmt.Errorf("word '%s': %w", word, err)
+			return nil, fmt.Errorf("word '%s': %v", word, err)
 		}
 
 		res = append(res, iw)
@@ -153,7 +153,7 @@ func (i *Inspector) individualWord(ctx context.Context,
 ) (*models.C11yWordsResponseIndividualWordsItems0, error) {
 	ok, err := i.client.IsWordPresent(ctx, word)
 	if err != nil {
-		return nil, fmt.Errorf("could not check word presence:  %w", err)
+		return nil, fmt.Errorf("could not check word presence:  %v", err)
 	}
 
 	if !ok {
diff --git a/modules/text2vec-contextionary/vectorizer/schema_config.go b/modules/text2vec-contextionary/vectorizer/schema_config.go
index 78a5d20d8a..c419df43ae 100644
--- a/modules/text2vec-contextionary/vectorizer/schema_config.go
+++ b/modules/text2vec-contextionary/vectorizer/schema_config.go
@@ -91,7 +91,7 @@ func (cv *ConfigValidator) validateClassName(ctx context.Context, className stri
 		word := strings.ToLower(part)
 		sw, err := cv.remote.IsStopWord(ctx, word)
 		if err != nil {
-			return fmt.Errorf("check stopword: %w", err)
+			return fmt.Errorf("check stopword: %v", err)
 		}
 
 		if sw {
@@ -101,7 +101,7 @@ func (cv *ConfigValidator) validateClassName(ctx context.Context, className stri
 
 		present, err := cv.remote.IsWordPresent(ctx, word)
 		if err != nil {
-			return fmt.Errorf("check word presence: %w", err)
+			return fmt.Errorf("check word presence: %v", err)
 		}
 
 		if !present {
@@ -134,7 +134,7 @@ func (cv *ConfigValidator) validatePropertyName(ctx context.Context,
 		word := strings.ToLower(part)
 		sw, err := cv.remote.IsStopWord(ctx, word)
 		if err != nil {
-			return fmt.Errorf("check stopword: %w", err)
+			return fmt.Errorf("check stopword: %v", err)
 		}
 
 		if sw {
@@ -144,7 +144,7 @@ func (cv *ConfigValidator) validatePropertyName(ctx context.Context,
 
 		present, err := cv.remote.IsWordPresent(ctx, word)
 		if err != nil {
-			return fmt.Errorf("check word presence: %w", err)
+			return fmt.Errorf("check word presence: %v", err)
 		}
 
 		if !present {
diff --git a/modules/text2vec-contextionary/vectorizer/vectorizer.go b/modules/text2vec-contextionary/vectorizer/vectorizer.go
index deef835b2b..66019d2340 100644
--- a/modules/text2vec-contextionary/vectorizer/vectorizer.go
+++ b/modules/text2vec-contextionary/vectorizer/vectorizer.go
@@ -17,12 +17,10 @@ package vectorizer
 
 import (
 	"context"
-	"errors"
 	"fmt"
 	"strings"
 
 	"github.com/fatih/camelcase"
-
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/entities/moduletools"
 	txt2vecmodels "github.com/weaviate/weaviate/modules/text2vec-contextionary/additional/models"
@@ -102,8 +100,8 @@ func (v *Vectorizer) object(ctx context.Context, object *models.Object, override
 
 	vector, ie, err := v.client.VectorForCorpi(ctx, []string{corpi}, overrides)
 	if err != nil {
-		switch {
-		case errors.As(err, &ErrNoUsableWords{}):
+		switch err.(type) {
+		case ErrNoUsableWords:
 			return nil, nil, fmt.Errorf("The object is invalid, as weaviate could not extract "+
 				"any contextionary-valid words from it. This is the case when you have "+
 				"set the options 'vectorizeClassName: false' and 'vectorizePropertyName: false' in this class' schema definition "+
@@ -127,7 +125,7 @@ func (v *Vectorizer) object(ctx context.Context, object *models.Object, override
 				"\n\nTo learn more about the contextionary and how it behaves, check out: https://www.semi.technology/documentation/weaviate/current/contextionary.html"+
 				"\n\nOriginal error: %v", corpi, err)
 		default:
-			return nil, nil, fmt.Errorf("vectorizing object with corpus '%+v': %w", corpi, err)
+			return nil, nil, fmt.Errorf("vectorizing object with corpus '%+v': %v", corpi, err)
 		}
 	}
 
@@ -145,7 +143,7 @@ func (v *Vectorizer) Corpi(ctx context.Context, corpi []string,
 
 	vector, _, err := v.client.VectorForCorpi(ctx, corpiTmp, nil)
 	if err != nil {
-		return nil, fmt.Errorf("vectorizing corpus '%+v': %w", corpiTmp, err)
+		return nil, fmt.Errorf("vectorizing corpus '%+v': %v", corpiTmp, err)
 	}
 
 	return vector, nil
diff --git a/tools/license_headers/main.go b/tools/license_headers/main.go
index 4004fe25d9..f57b61d14e 100644
--- a/tools/license_headers/main.go
+++ b/tools/license_headers/main.go
@@ -50,13 +50,13 @@ func main() {
 func processSingleFile(name string) error {
 	bytes, err := os.ReadFile(name)
 	if err != nil {
-		return fmt.Errorf("%s: %w", name, err)
+		return fmt.Errorf("%s: %v", name, err)
 	}
 
 	if hasNoHeader(bytes, name) {
 		err := extendWithHeader(name, bytes)
 		if err != nil {
-			return fmt.Errorf("%s: %w", name, err)
+			return fmt.Errorf("%s: %v", name, err)
 		}
 		fmt.Printf("🖋️  successfully created header: %s\n", name)
 		return nil
@@ -65,7 +65,7 @@ func processSingleFile(name string) error {
 	if headerNeedsUpdate(bytes) {
 		err := updateHeader(name, bytes)
 		if err != nil {
-			return fmt.Errorf("%s: %w", name, err)
+			return fmt.Errorf("%s: %v", name, err)
 		}
 
 		fmt.Printf("👷 successfully updated: %s\n", name)
diff --git a/usecases/auth/authentication/oidc/middleware.go b/usecases/auth/authentication/oidc/middleware.go
index 2a208b0a73..78dc78cab0 100644
--- a/usecases/auth/authentication/oidc/middleware.go
+++ b/usecases/auth/authentication/oidc/middleware.go
@@ -46,7 +46,7 @@ func New(cfg config.Config) (*Client, error) {
 	}
 
 	if err := client.init(); err != nil {
-		return nil, fmt.Errorf("oidc init: %w", err)
+		return nil, fmt.Errorf("oidc init: %v", err)
 	}
 
 	return client, nil
@@ -54,12 +54,12 @@ func New(cfg config.Config) (*Client, error) {
 
 func (c *Client) init() error {
 	if err := c.validateConfig(); err != nil {
-		return fmt.Errorf("invalid config: %w", err)
+		return fmt.Errorf("invalid config: %v", err)
 	}
 
 	provider, err := oidc.NewProvider(context.Background(), c.config.Issuer)
 	if err != nil {
-		return fmt.Errorf("could not setup provider: %w", err)
+		return fmt.Errorf("could not setup provider: %v", err)
 	}
 	c.provider = provider
 
@@ -129,7 +129,7 @@ func (c *Client) ValidateAndExtract(token string, scopes []string) (*models.Prin
 func (c *Client) extractClaims(token *oidc.IDToken) (map[string]interface{}, error) {
 	var claims map[string]interface{}
 	if err := token.Claims(&claims); err != nil {
-		return nil, fmt.Errorf("could not extract claims from token: %w", err)
+		return nil, fmt.Errorf("could not extract claims from token: %v", err)
 	}
 
 	return claims, nil
diff --git a/usecases/backup/backend.go b/usecases/backup/backend.go
index 9708d48679..722d6fd937 100644
--- a/usecases/backup/backend.go
+++ b/usecases/backup/backend.go
@@ -24,11 +24,11 @@ import (
 	"sync/atomic"
 	"time"
 
+	enterrors "github.com/weaviate/weaviate/entities/errors"
+
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/entities/backup"
-	enterrors "github.com/weaviate/weaviate/entities/errors"
 	"github.com/weaviate/weaviate/entities/modulecapabilities"
 	"github.com/weaviate/weaviate/usecases/monitoring"
 )
@@ -224,7 +224,7 @@ func (u *uploader) all(ctx context.Context, classes []string, desc *backup.Backu
 				desc.Status = string(backup.Cancelled)
 				u.releaseIndexes(classes, desc.ID)
 			}
-			err = fmt.Errorf("upload %w: %w", err, u.backend.PutMeta(ctx, desc, overrideBucket, overridePath))
+			err = fmt.Errorf("upload %w: %v", err, u.backend.PutMeta(ctx, desc, overrideBucket, overridePath))
 		} else {
 			u.log.Info("start uploading meta data")
 			if err = u.backend.PutMeta(ctx, desc, overrideBucket, overridePath); err != nil {
diff --git a/usecases/backup/backupper.go b/usecases/backup/backupper.go
index 5c10625fc1..3cd3f47c76 100644
--- a/usecases/backup/backupper.go
+++ b/usecases/backup/backupper.go
@@ -17,10 +17,10 @@ import (
 	"fmt"
 	"time"
 
-	"github.com/sirupsen/logrus"
+	enterrors "github.com/weaviate/weaviate/entities/errors"
 
+	"github.com/sirupsen/logrus"
 	"github.com/weaviate/weaviate/entities/backup"
-	enterrors "github.com/weaviate/weaviate/entities/errors"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/usecases/config"
 )
@@ -107,7 +107,7 @@ func (b *backupper) OnStatus(ctx context.Context, req *StatusRequest) (reqState,
 	meta, err := store.Meta(ctx, req.ID, store.bucket, store.path, false)
 	if err != nil {
 		path := fmt.Sprintf("%s/%s", req.ID, BackupFile)
-		return reqState{}, fmt.Errorf("cannot get status while backing up: %w: %q: %w", errMetaNotFound, path, err)
+		return reqState{}, fmt.Errorf("cannot get status while backing up: %w: %q: %v", errMetaNotFound, path, err)
 	}
 	if err != nil || meta.Error != "" {
 		return reqState{}, errors.New(meta.Error)
diff --git a/usecases/backup/coordinator.go b/usecases/backup/coordinator.go
index 3c8fbcc85b..6d6e0e731a 100644
--- a/usecases/backup/coordinator.go
+++ b/usecases/backup/coordinator.go
@@ -21,11 +21,11 @@ import (
 	"sync/atomic"
 	"time"
 
-	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/cluster/types"
-	"github.com/weaviate/weaviate/entities/backup"
 	enterrors "github.com/weaviate/weaviate/entities/errors"
+
+	"github.com/sirupsen/logrus"
+	"github.com/weaviate/weaviate/entities/backup"
 	"github.com/weaviate/weaviate/usecases/config"
 )
 
@@ -325,7 +325,7 @@ func (c *coordinator) OnStatus(ctx context.Context, store coordStore, req *Statu
 	meta, err := store.Meta(ctx, filename, store.bucket, store.path)
 	if err != nil {
 		path := st.Path
-		return nil, fmt.Errorf("coordinator cannot get status: %w: %q: %w store: %v", errMetaNotFound, path, err, st)
+		return nil, fmt.Errorf("coordinator cannot get status: %w: %q: %v store: %v", errMetaNotFound, path, err, st)
 	}
 
 	status := &Status{
diff --git a/usecases/backup/scheduler.go b/usecases/backup/scheduler.go
index 5a3aaf9874..8254fc4bcb 100644
--- a/usecases/backup/scheduler.go
+++ b/usecases/backup/scheduler.go
@@ -18,7 +18,6 @@ import (
 	"time"
 
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/entities/backup"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/usecases/auth/authorization"
@@ -366,8 +365,11 @@ func (s *Scheduler) checkIfBackupExists(ctx context.Context, store coordStore, r
 	if err == nil && meta.Status != backup.Cancelled {
 		return fmt.Errorf("backup %q already exists at %q", req.ID, destPath)
 	}
-
-	if !errors.As(err, &backup.ErrNotFound{}) {
+	if _, ok := err.(backup.ErrNotFound); !ok {
+		return fmt.Errorf("check if backup %q exists at %q: %w", req.ID, destPath, err)
+	}
+	var errNotFound backup.ErrNotFound
+	if !errors.As(err, &errNotFound) {
 		return fmt.Errorf("check if backup %q exists at %q: %w", req.ID, destPath, err)
 	}
 	return nil
@@ -388,7 +390,7 @@ func (s *Scheduler) validateRestoreRequest(ctx context.Context, store coordStore
 	if err != nil {
 		notFoundErr := backup.ErrNotFound{}
 		if errors.As(err, &notFoundErr) {
-			return nil, fmt.Errorf("backup id %q does not exist: %w: %w", req.ID, notFoundErr, errMetaNotFound)
+			return nil, fmt.Errorf("backup id %q does not exist: %v: %w", req.ID, notFoundErr, errMetaNotFound)
 		}
 		return nil, fmt.Errorf("find backup %s: %w", destPath, err)
 	}
diff --git a/usecases/backup/zip.go b/usecases/backup/zip.go
index 2ca491cdf0..77dcae26aa 100644
--- a/usecases/backup/zip.go
+++ b/usecases/backup/zip.go
@@ -63,7 +63,7 @@ func (z *zip) Close() error {
 	var err1, err2, err3 error
 	err1 = z.w.Close()
 	err2 = z.gzw.Close()
-	if err := z.pipeWriter.Close(); err != nil && !errors.Is(err, io.ErrClosedPipe) {
+	if err := z.pipeWriter.Close(); err != nil && err != io.ErrClosedPipe {
 		err3 = err
 	}
 	if err1 != nil || err2 != nil || err3 != nil {
@@ -204,7 +204,7 @@ func (u *unzip) init() error {
 
 func (u *unzip) Close() (err error) {
 	var err1, err2 error
-	if err := u.pipeReader.Close(); err != nil && !errors.Is(err, io.ErrClosedPipe) {
+	if err := u.pipeReader.Close(); err != nil && err != io.ErrClosedPipe {
 		err1 = err
 	}
 	if u.gzr != nil {
diff --git a/usecases/classification/classifier.go b/usecases/classification/classifier.go
index 966dcb1443..14360f394b 100644
--- a/usecases/classification/classifier.go
+++ b/usecases/classification/classifier.go
@@ -17,15 +17,15 @@ import (
 	"fmt"
 	"time"
 
+	enterrors "github.com/weaviate/weaviate/entities/errors"
+
 	"github.com/go-openapi/strfmt"
 	"github.com/google/uuid"
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/adapters/handlers/rest/filterext"
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/dto"
-	enterrors "github.com/weaviate/weaviate/entities/errors"
 	libfilters "github.com/weaviate/weaviate/entities/filters"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/entities/modulecapabilities"
@@ -147,7 +147,7 @@ func (c *Classifier) Schedule(ctx context.Context, principal *models.Principal,
 	}
 
 	if err := c.assignNewID(&params); err != nil {
-		return nil, fmt.Errorf("classification: assign id: %w", err)
+		return nil, fmt.Errorf("classification: assign id: %v", err)
 	}
 
 	params.Status = models.ClassificationStatusRunning
@@ -156,7 +156,7 @@ func (c *Classifier) Schedule(ctx context.Context, principal *models.Principal,
 	}
 
 	if err := c.repo.Put(ctx, params); err != nil {
-		return nil, fmt.Errorf("classification: put: %w", err)
+		return nil, fmt.Errorf("classification: put: %v", err)
 	}
 
 	// asynchronously trigger the classification
@@ -177,17 +177,17 @@ func (c *Classifier) extractFilters(principal *models.Principal, params models.C
 
 	source, err := filterext.Parse(params.Filters.SourceWhere, params.Class)
 	if err != nil {
-		return classificationFilters{}, fmt.Errorf("field 'sourceWhere': %w", err)
+		return classificationFilters{}, fmt.Errorf("field 'sourceWhere': %v", err)
 	}
 
 	trainingSet, err := filterext.Parse(params.Filters.TrainingSetWhere, params.Class)
 	if err != nil {
-		return classificationFilters{}, fmt.Errorf("field 'trainingSetWhere': %w", err)
+		return classificationFilters{}, fmt.Errorf("field 'trainingSetWhere': %v", err)
 	}
 
 	target, err := filterext.Parse(params.Filters.TargetWhere, params.Class)
 	if err != nil {
-		return classificationFilters{}, fmt.Errorf("field 'targetWhere': %w", err)
+		return classificationFilters{}, fmt.Errorf("field 'targetWhere': %v", err)
 	}
 
 	filters := classificationFilters{
@@ -206,19 +206,19 @@ func (c *Classifier) extractFilters(principal *models.Principal, params models.C
 func (c *Classifier) validateFilters(principal *models.Principal, params *models.Classification, filters *classificationFilters) (err error) {
 	if params.Type == TypeKNN {
 		if err = c.validateFilter(principal, filters.Source()); err != nil {
-			return fmt.Errorf("invalid sourceWhere: %w", err)
+			return fmt.Errorf("invalid sourceWhere: %s", err)
 		}
 		if err = c.validateFilter(principal, filters.TrainingSet()); err != nil {
-			return fmt.Errorf("invalid trainingSetWhere: %w", err)
+			return fmt.Errorf("invalid trainingSetWhere: %s", err)
 		}
 	}
 
 	if params.Type == TypeContextual || params.Type == TypeZeroShot {
 		if err = c.validateFilter(principal, filters.Source()); err != nil {
-			return fmt.Errorf("invalid sourceWhere: %w", err)
+			return fmt.Errorf("invalid sourceWhere: %s", err)
 		}
 		if err = c.validateFilter(principal, filters.Target()); err != nil {
-			return fmt.Errorf("invalid targetWhere: %w", err)
+			return fmt.Errorf("invalid targetWhere: %s", err)
 		}
 	}
 
diff --git a/usecases/classification/classifier_run_knn.go b/usecases/classification/classifier_run_knn.go
index ab0034d5e0..a02925763f 100644
--- a/usecases/classification/classifier_run_knn.go
+++ b/usecases/classification/classifier_run_knn.go
@@ -33,7 +33,7 @@ func (c *Classifier) classifyItemUsingKNN(item search.Result, itemIndex int,
 		item.ClassName,
 		params.ClassifyProperties, int(*settings.K), filters.TrainingSet())
 	if err != nil {
-		return fmt.Errorf("classify %s/%s: %w", item.ClassName, item.ID, err)
+		return fmt.Errorf("classify %s/%s: %v", item.ClassName, item.ID, err)
 	}
 
 	var classified []string
@@ -55,7 +55,7 @@ func (c *Classifier) classifyItemUsingKNN(item search.Result, itemIndex int,
 	c.extendItemWithObjectMeta(&item, params, classified)
 	err = writer.Store(item)
 	if err != nil {
-		return fmt.Errorf("store %s/%s: %w", item.ClassName, item.ID, err)
+		return fmt.Errorf("store %s/%s: %v", item.ClassName, item.ID, err)
 	}
 
 	return nil
diff --git a/usecases/classification/validation.go b/usecases/classification/validation.go
index 5ee6fe9b84..52bb4995ce 100644
--- a/usecases/classification/validation.go
+++ b/usecases/classification/validation.go
@@ -44,7 +44,7 @@ func (v *Validator) Do() error {
 
 	err := v.errors.ToError()
 	if err != nil {
-		return fmt.Errorf("invalid classification: %w", err)
+		return fmt.Errorf("invalid classification: %v", err)
 	}
 
 	return nil
diff --git a/usecases/config/authorization.go b/usecases/config/authorization.go
index 0718900da1..95ede26ae4 100644
--- a/usecases/config/authorization.go
+++ b/usecases/config/authorization.go
@@ -14,8 +14,9 @@ package config
 import (
 	"fmt"
 
-	"github.com/weaviate/weaviate/usecases/auth/authorization/adminlist"
 	"github.com/weaviate/weaviate/usecases/auth/authorization/rbac/rbacconf"
+
+	"github.com/weaviate/weaviate/usecases/auth/authorization/adminlist"
 )
 
 // Authorization configuration
@@ -34,13 +35,13 @@ func (a Authorization) Validate() error {
 
 	if a.AdminList.Enabled {
 		if err := a.AdminList.Validate(); err != nil {
-			return fmt.Errorf("authorization adminlist: %w", err)
+			return fmt.Errorf("authorization adminlist: %s", err)
 		}
 	}
 
 	if a.Rbac.Enabled {
 		if err := a.Rbac.Validate(); err != nil {
-			return fmt.Errorf("authorization rbac: %w", err)
+			return fmt.Errorf("authorization rbac: %s", err)
 		}
 	}
 
diff --git a/usecases/config/config_handler.go b/usecases/config/config_handler.go
index 0398ab5d0e..6264fb2b2a 100644
--- a/usecases/config/config_handler.go
+++ b/usecases/config/config_handler.go
@@ -529,12 +529,12 @@ func (f *WeaviateConfig) parseConfigFile(file []byte, name string) (Config, erro
 	case "json":
 		err := json.Unmarshal(file, &config)
 		if err != nil {
-			return config, fmt.Errorf("error unmarshalling the json config file: %w", err)
+			return config, fmt.Errorf("error unmarshalling the json config file: %s", err)
 		}
 	case "yaml":
 		err := yaml.Unmarshal(file, &config)
 		if err != nil {
-			return config, fmt.Errorf("error unmarshalling the yaml config file: %w", err)
+			return config, fmt.Errorf("error unmarshalling the yaml config file: %s", err)
 		}
 	default:
 		return config, fmt.Errorf("unsupported config file extension '%s', use .yaml or .json", m[1])
@@ -575,5 +575,5 @@ func (f *WeaviateConfig) fromFlags(flags *Flags) {
 }
 
 func configErr(err error) error {
-	return fmt.Errorf("invalid config: %w", err)
+	return fmt.Errorf("invalid config: %v", err)
 }
diff --git a/usecases/connstate/manager.go b/usecases/connstate/manager.go
index 090bb4a977..6e32770ce1 100644
--- a/usecases/connstate/manager.go
+++ b/usecases/connstate/manager.go
@@ -37,7 +37,7 @@ type Repo interface {
 func NewManager(repo Repo, logger logrus.FieldLogger) (*Manager, error) {
 	m := &Manager{repo: repo, logger: logger}
 	if err := m.loadOrInitialize(context.Background()); err != nil {
-		return nil, fmt.Errorf("could not load or initialize: %w", err)
+		return nil, fmt.Errorf("could not load or initialize: %v", err)
 	}
 
 	return m, nil
@@ -62,7 +62,7 @@ func (m *Manager) SetState(ctx context.Context, state json.RawMessage) error {
 func (m *Manager) loadOrInitialize(ctx context.Context) error {
 	state, err := m.repo.Load(ctx)
 	if err != nil {
-		return fmt.Errorf("could not load connector state: %w", err)
+		return fmt.Errorf("could not load connector state: %v", err)
 	}
 
 	if state == nil {
@@ -82,7 +82,7 @@ func (m *Manager) save(ctx context.Context) error {
 
 	err := m.repo.Save(ctx, m.state)
 	if err != nil {
-		return fmt.Errorf("could not save connector state: %w", err)
+		return fmt.Errorf("could not save connector state: %v", err)
 	}
 
 	return nil
diff --git a/usecases/objects/add.go b/usecases/objects/add.go
index 06fd1c0697..a640d49a4a 100644
--- a/usecases/objects/add.go
+++ b/usecases/objects/add.go
@@ -13,13 +13,13 @@ package objects
 
 import (
 	"context"
-	"errors"
 	"fmt"
 	"strings"
 
+	"github.com/pkg/errors"
+
 	"github.com/go-openapi/strfmt"
 	"github.com/google/uuid"
-
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/classcache"
 	enterrors "github.com/weaviate/weaviate/entities/errors"
@@ -87,7 +87,7 @@ func (m *Manager) addObjectToConnectorAndSchema(ctx context.Context, principal *
 
 	schemaVersion, err := m.autoSchemaManager.autoSchema(ctx, principal, true, vclasses, object)
 	if err != nil {
-		return nil, fmt.Errorf("invalid object: %w", err)
+		return nil, errors.Wrap(err, "invalid object")
 	}
 
 	if _, _, err = m.autoSchemaManager.autoTenants(ctx, principal, []*models.Object{object}); err != nil {
@@ -145,10 +145,12 @@ func (m *Manager) checkIDOrAssignNew(ctx context.Context, principal *models.Prin
 	if exists {
 		return "", NewErrInvalidUserInput("id '%s' already exists", id)
 	} else if err != nil {
+		var errInvalidUserInput ErrInvalidUserInput
+		var errMultiTenancy ErrMultiTenancy
 		switch {
-		case errors.As(err, &ErrInvalidUserInput{}):
+		case errors.As(err, &errInvalidUserInput):
 			return "", err
-		case errors.As(err, &ErrMultiTenancy{}):
+		case errors.As(err, &errMultiTenancy):
 			// This may be fine, the class is configured to create non-existing tenants.
 			// A non-existing tenant will still be detected later on
 			if enterrors.IsTenantNotFound(err) {
diff --git a/usecases/objects/batch_delete.go b/usecases/objects/batch_delete.go
index e6343edadd..3a4d9c63e2 100644
--- a/usecases/objects/batch_delete.go
+++ b/usecases/objects/batch_delete.go
@@ -17,7 +17,6 @@ import (
 	"time"
 
 	"github.com/pkg/errors"
-
 	"github.com/weaviate/weaviate/adapters/handlers/rest/filterext"
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/classcache"
@@ -138,7 +137,7 @@ func (b *BatchManager) validateBatchDelete(ctx context.Context, principal *model
 	// Validate schema given in body with the weaviate schema
 	vclasses, err := b.schemaManager.GetCachedClass(ctx, principal, match.Class)
 	if err != nil {
-		return nil, 0, fmt.Errorf("failed to get class: %s: %w", match.Class, err)
+		return nil, 0, errors.Wrapf(err, "failed to get class: %s", match.Class)
 	}
 	if vclasses[match.Class].Class == nil {
 		return nil, 0, fmt.Errorf("failed to get class: %s", match.Class)
@@ -147,12 +146,12 @@ func (b *BatchManager) validateBatchDelete(ctx context.Context, principal *model
 
 	filter, err := filterext.Parse(match.Where, class.Class)
 	if err != nil {
-		return nil, 0, fmt.Errorf("failed to parse where filter: %w", err)
+		return nil, 0, errors.Wrapf(err, "failed to parse where filter")
 	}
 
 	err = filters.ValidateFilters(b.classGetterFunc(principal), filter)
 	if err != nil {
-		return nil, 0, fmt.Errorf("invalid where filter: %w", err)
+		return nil, 0, errors.Wrapf(err, "invalid where filter")
 	}
 
 	dryRunParam := false
diff --git a/usecases/objects/batch_references_add.go b/usecases/objects/batch_references_add.go
index 942906dd1f..c78eefa185 100644
--- a/usecases/objects/batch_references_add.go
+++ b/usecases/objects/batch_references_add.go
@@ -17,8 +17,9 @@ import (
 	"strings"
 	"sync"
 
+	"github.com/weaviate/weaviate/entities/versioned"
+
 	"github.com/go-openapi/strfmt"
-	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
 
 	"github.com/weaviate/weaviate/entities/additional"
@@ -39,26 +40,42 @@ func (b *BatchManager) AddReferences(ctx context.Context, principal *models.Prin
 		return nil, NewErrInvalidUserInput("invalid params: %v", err)
 	}
 
+	ctx = classcache.ContextWithClassCache(ctx)
+
 	batchReferences := validateReferencesConcurrently(ctx, refs, b.logger)
 
-	var pathsData []string
-	var pathsMetadata []string
+	uniqueClass := map[string]struct{}{}
+	type classAndShard struct {
+		Class string
+		Shard string
+	}
+	uniqueClassShard := map[string]classAndShard{}
 	for idx := range batchReferences {
 		if batchReferences[idx].Err != nil {
 			continue
 		}
 		class := batchReferences[idx].From.Class.String()
-		pathsData = append(pathsData, authorization.ShardsData(class, batchReferences[idx].Tenant)...)
-		pathsMetadata = append(pathsMetadata, authorization.CollectionsMetadata(class)...)
+		uniqueClass[class] = struct{}{}
+		uniqueClassShard[class+"#"+batchReferences[idx].Tenant] = classAndShard{Class: class, Shard: batchReferences[idx].Tenant}
 	}
 
-	if err := b.authorizer.Authorize(principal, authorization.UPDATE, pathsData...); err != nil {
+	allClasses := make([]string, 0, len(uniqueClass))
+	for classname := range uniqueClass {
+		allClasses = append(allClasses, classname)
+	}
+	fetchedClasses, err := b.schemaManager.GetCachedClass(ctx, principal, allClasses...)
+	if err != nil {
 		return nil, err
 	}
-	if err := b.authorizer.Authorize(principal, authorization.READ, pathsMetadata...); err != nil {
+
+	var pathsData []string
+	for _, val := range uniqueClassShard {
+		pathsData = append(pathsData, authorization.ShardsData(val.Class, val.Shard)...)
+	}
+
+	if err := b.authorizer.Authorize(principal, authorization.UPDATE, pathsData...); err != nil {
 		return nil, err
 	}
-	ctx = classcache.ContextWithClassCache(ctx)
 
 	unlock, err := b.locks.LockSchema()
 	if err != nil {
@@ -69,18 +86,22 @@ func (b *BatchManager) AddReferences(ctx context.Context, principal *models.Prin
 	b.metrics.BatchRefInc()
 	defer b.metrics.BatchRefDec()
 
-	return b.addReferences(ctx, principal, batchReferences, repl)
+	return b.addReferences(ctx, principal, batchReferences, repl, fetchedClasses)
 }
 
 func (b *BatchManager) addReferences(ctx context.Context, principal *models.Principal,
-	refs BatchReferences, repl *additional.ReplicationProperties,
+	refs BatchReferences, repl *additional.ReplicationProperties, fetchedClasses map[string]versioned.Class,
 ) (BatchReferences, error) {
-	if err := b.autodetectToClass(ctx, principal, refs); err != nil {
+	if err := b.autodetectToClass(refs, fetchedClasses); err != nil {
 		return nil, err
 	}
 
 	// MT validation must be done after auto-detection as we cannot know the target class beforehand in all cases
-	var shardsDataPaths []string
+	type classAndShard struct {
+		Class string
+		Shard string
+	}
+	uniqueClassShard := map[string]classAndShard{}
 	var schemaVersion uint64
 	for i, ref := range refs {
 		if ref.Err != nil {
@@ -89,7 +110,7 @@ func (b *BatchManager) addReferences(ctx context.Context, principal *models.Prin
 
 		if shouldValidateMultiTenantRef(ref.Tenant, ref.From, ref.To) {
 			// can only validate multi-tenancy when everything above succeeds
-			classVersion, err := validateReferenceMultiTenancy(ctx, principal, b.schemaManager, b.vectorRepo, ref.From, ref.To, ref.Tenant)
+			classVersion, err := validateReferenceMultiTenancy(ctx, principal, b.schemaManager, b.vectorRepo, ref.From, ref.To, ref.Tenant, fetchedClasses)
 			if err != nil {
 				refs[i].Err = err
 			}
@@ -98,7 +119,12 @@ func (b *BatchManager) addReferences(ctx context.Context, principal *models.Prin
 			}
 		}
 
-		shardsDataPaths = append(shardsDataPaths, authorization.ShardsData(ref.To.Class, ref.Tenant)...)
+		uniqueClassShard[ref.To.Class+"#"+ref.Tenant] = classAndShard{Class: ref.To.Class, Shard: ref.Tenant}
+	}
+
+	shardsDataPaths := make([]string, 0, len(uniqueClassShard))
+	for _, val := range uniqueClassShard {
+		shardsDataPaths = append(shardsDataPaths, authorization.ShardsData(val.Class, val.Shard)...)
 	}
 
 	// target object is checked for existence - this is currently ONLY done with tenants enabled, but we should require
@@ -145,9 +171,7 @@ func validateReferencesConcurrently(ctx context.Context, refs []*models.BatchRef
 }
 
 // autodetectToClass gets the class name of the referenced class through the schema definition
-func (b *BatchManager) autodetectToClass(ctx context.Context,
-	principal *models.Principal, batchReferences BatchReferences,
-) error {
+func (b *BatchManager) autodetectToClass(batchReferences BatchReferences, fetchedClasses map[string]versioned.Class) error {
 	classPropTarget := make(map[string]string, len(batchReferences))
 	for i, ref := range batchReferences {
 		// get to class from property datatype
@@ -159,17 +183,13 @@ func (b *BatchManager) autodetectToClass(ctx context.Context,
 
 		target, ok := classPropTarget[className+propName]
 		if !ok {
-			vClasses, err := b.schemaManager.GetCachedClass(ctx, principal, className)
-			if err != nil {
-				batchReferences[i].Err = errors.Wrapf(err, "could not fetch class %v", className)
-				continue
-			}
-			if vClasses[className].Class == nil {
+			class := fetchedClasses[className]
+			if class.Class == nil {
 				batchReferences[i].Err = fmt.Errorf("source class %q not found in schema", className)
 				continue
 			}
 
-			prop, err := schema.GetPropertyByName(vClasses[className].Class, propName)
+			prop, err := schema.GetPropertyByName(class.Class, propName)
 			if err != nil {
 				batchReferences[i].Err = fmt.Errorf("property %s does not exist for class %s", propName, className)
 				continue
@@ -230,14 +250,14 @@ func validateReference(ctx context.Context,
 func validateReferenceMultiTenancy(ctx context.Context,
 	principal *models.Principal, schemaManager schemaManager,
 	repo VectorRepo, source *crossref.RefSource, target *crossref.Ref,
-	tenant string,
+	tenant string, fetchedClasses map[string]versioned.Class,
 ) (uint64, error) {
 	if source == nil || target == nil {
 		return 0, fmt.Errorf("can't validate multi-tenancy for nil refs")
 	}
 
 	sourceClass, targetClass, schemaVersion, err := getReferenceClasses(
-		ctx, principal, schemaManager, source.Class.String(), source.Property.String(), target.Class)
+		ctx, principal, schemaManager, source.Class.String(), source.Property.String(), target.Class, fetchedClasses)
 	if err != nil {
 		return 0, err
 	}
@@ -273,7 +293,7 @@ func validateReferenceMultiTenancy(ctx context.Context,
 
 func getReferenceClasses(ctx context.Context,
 	principal *models.Principal, schemaManager schemaManager,
-	classFrom, fromProperty, classTo string,
+	classFrom, fromProperty, toClassName string, fetchedClasses map[string]versioned.Class,
 ) (sourceClass *models.Class, targetClass *models.Class, schemaVersion uint64, err error) {
 	if classFrom == "" {
 		err = fmt.Errorf("references involving a multi-tenancy enabled class " +
@@ -281,21 +301,17 @@ func getReferenceClasses(ctx context.Context,
 		return
 	}
 
-	vclasses, err := schemaManager.GetCachedClass(ctx, principal, classFrom)
-	if err != nil {
-		err = fmt.Errorf("get source class %q: %w", classFrom, err)
-		return
-	}
-	if vclasses[classFrom].Class == nil {
+	fromClass := fetchedClasses[classFrom]
+	if fromClass.Class == nil {
 		err = fmt.Errorf("source class %q not found in schema", classFrom)
 		return
 	}
 
-	sourceClass = vclasses[classFrom].Class
-	schemaVersion = vclasses[classFrom].Version
+	sourceClass = fromClass.Class
+	schemaVersion = fromClass.Version
 
 	// we can auto-detect the to class from the schema if it is a single target reference
-	if classTo == "" {
+	if toClassName == "" {
 		refProp, err2 := schema.GetPropertyByName(sourceClass, fromProperty)
 		if err2 != nil {
 			err = fmt.Errorf("get source refprop %q: %w", classFrom, err2)
@@ -306,19 +322,24 @@ func getReferenceClasses(ctx context.Context,
 			err = fmt.Errorf("multi-target references require the class name in the target beacon url")
 			return
 		}
-		classTo = refProp.DataType[0]
+		toClassName = refProp.DataType[0]
 	}
 
-	targetVclasses, err := schemaManager.GetCachedClass(ctx, principal, classTo)
-	if err != nil {
-		err = fmt.Errorf("get target class %q: %w", classTo, err)
-		return
+	toClass, ok := fetchedClasses[toClassName]
+	if !ok {
+		targetVclasses, err2 := schemaManager.GetCachedClass(ctx, principal, toClassName)
+		if err2 != nil {
+			err = fmt.Errorf("get target class %q: %w", toClassName, err2)
+			return
+		}
+		toClass = targetVclasses[toClassName]
+		fetchedClasses[toClassName] = toClass
 	}
-	if targetVclasses[classTo].Class == nil {
+	if toClass.Class == nil {
 		err = fmt.Errorf("target class %q not found in schema", classFrom)
 		return
 	}
-	targetClass = targetVclasses[classTo].Class
+	targetClass = toClass.Class
 
 	return
 }
diff --git a/usecases/objects/delete.go b/usecases/objects/delete.go
index 58ee2b702a..a0c5586ea0 100644
--- a/usecases/objects/delete.go
+++ b/usecases/objects/delete.go
@@ -18,7 +18,6 @@ import (
 	"time"
 
 	"github.com/go-openapi/strfmt"
-
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/classcache"
 	"github.com/weaviate/weaviate/entities/models"
@@ -103,7 +102,8 @@ func (m *Manager) deleteObjectFromRepo(ctx context.Context, id strfmt.UUID, dele
 	for {
 		objectRes, err := m.getObjectFromRepo(ctx, "", id, additional.Properties{}, nil, "")
 		if err != nil {
-			if errors.As(err, &ErrNotFound{}) {
+			_, ok := err.(ErrNotFound)
+			if ok {
 				if deleteCounter == 0 {
 					return err
 				}
diff --git a/usecases/objects/get.go b/usecases/objects/get.go
index c11731fee2..075878bcbf 100644
--- a/usecases/objects/get.go
+++ b/usecases/objects/get.go
@@ -18,7 +18,6 @@ import (
 	"strings"
 
 	"github.com/go-openapi/strfmt"
-
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/filters"
 	"github.com/weaviate/weaviate/entities/models"
@@ -120,8 +119,9 @@ func (m *Manager) getObjectFromRepo(ctx context.Context, class string, id strfmt
 		res, err = m.vectorRepo.ObjectByID(ctx, id, search.SelectProperties{}, adds, tenant)
 	}
 	if err != nil {
+		var errMultiTenancy ErrMultiTenancy
 		switch {
-		case errors.As(err, &ErrMultiTenancy{}):
+		case errors.As(err, &errMultiTenancy):
 			return nil, NewErrMultiTenancy(fmt.Errorf("repo: object by id: %w", err))
 		default:
 			if errors.As(err, &authzerrs.Forbidden{}) {
@@ -138,7 +138,7 @@ func (m *Manager) getObjectFromRepo(ctx context.Context, class string, id strfmt
 	if m.modulesProvider != nil {
 		res, err = m.modulesProvider.GetObjectAdditionalExtend(ctx, res, adds.ModuleParams)
 		if err != nil {
-			return nil, fmt.Errorf("get extend: %w", err)
+			return nil, fmt.Errorf("get extend: %v", err)
 		}
 	}
 
diff --git a/usecases/objects/head.go b/usecases/objects/head.go
index b2cc3b4f35..c2d81d251c 100644
--- a/usecases/objects/head.go
+++ b/usecases/objects/head.go
@@ -16,7 +16,6 @@ import (
 	"errors"
 
 	"github.com/go-openapi/strfmt"
-
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/usecases/auth/authorization"
@@ -44,8 +43,8 @@ func (m *Manager) HeadObject(ctx context.Context, principal *models.Principal, c
 
 	ok, err := m.vectorRepo.Exists(ctx, class, id, repl, tenant)
 	if err != nil {
-		switch {
-		case errors.As(err, &ErrMultiTenancy{}):
+		switch err.(type) {
+		case ErrMultiTenancy:
 			return false, &Error{"repo.exists", StatusUnprocessableEntity, err}
 		default:
 			if (errors.As(err, &ErrDirtyReadOfDeletedObject{})) {
diff --git a/usecases/objects/manager.go b/usecases/objects/manager.go
index e4a5359efe..c6e2b44b15 100644
--- a/usecases/objects/manager.go
+++ b/usecases/objects/manager.go
@@ -183,7 +183,7 @@ func NewManager(locks locks, schemaManager schemaManager,
 func generateUUID() (strfmt.UUID, error) {
 	id, err := uuid.NewRandom()
 	if err != nil {
-		return "", fmt.Errorf("could not generate uuid v4: %w", err)
+		return "", fmt.Errorf("could not generate uuid v4: %v", err)
 	}
 
 	return strfmt.UUID(id.String()), nil
diff --git a/usecases/objects/merge.go b/usecases/objects/merge.go
index f043c7be47..57df649375 100644
--- a/usecases/objects/merge.go
+++ b/usecases/objects/merge.go
@@ -17,7 +17,6 @@ import (
 	"fmt"
 
 	"github.com/go-openapi/strfmt"
-
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/classcache"
 	"github.com/weaviate/weaviate/entities/models"
@@ -66,8 +65,9 @@ func (m *Manager) MergeObject(ctx context.Context, principal *models.Principal,
 	ctx = classcache.ContextWithClassCache(ctx)
 	obj, err := m.vectorRepo.Object(ctx, cls, id, nil, additional.Properties{}, repl, updates.Tenant)
 	if err != nil {
+		var errMultiTenancy ErrMultiTenancy
 		switch {
-		case errors.As(err, &ErrMultiTenancy{}):
+		case errors.As(err, &errMultiTenancy):
 			return &Error{"repo.object", StatusUnprocessableEntity, err}
 		default:
 			if errors.As(err, &ErrDirtyReadOfDeletedObject{}) || errors.As(err, &ErrDirtyWriteOfDeletedObject{}) {
diff --git a/usecases/objects/references_add.go b/usecases/objects/references_add.go
index 0b533f2894..ef3d0dfecb 100644
--- a/usecases/objects/references_add.go
+++ b/usecases/objects/references_add.go
@@ -21,7 +21,6 @@ import (
 	"github.com/weaviate/weaviate/usecases/auth/authorization"
 
 	"github.com/go-openapi/strfmt"
-
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/classcache"
 	"github.com/weaviate/weaviate/entities/models"
@@ -44,9 +43,6 @@ func (m *Manager) AddObjectReference(ctx context.Context, principal *models.Prin
 	if err := m.authorizer.Authorize(principal, authorization.UPDATE, authorization.ShardsData(input.Class, tenant)...); err != nil {
 		return &Error{err.Error(), StatusForbidden, err}
 	}
-	if err := m.authorizer.Authorize(principal, authorization.READ, authorization.CollectionsMetadata(input.Class)...); err != nil {
-		return &Error{err.Error(), StatusForbidden, err}
-	}
 
 	deprecatedEndpoint := input.Class == ""
 	if deprecatedEndpoint { // for backward compatibility only
@@ -67,13 +63,23 @@ func (m *Manager) AddObjectReference(ctx context.Context, principal *models.Prin
 		input.Class = objectRes.Object().Class
 	}
 
+	fetchedClass, err := m.schemaManager.GetCachedClass(ctx, principal, input.Class)
+	if err != nil {
+		if errors.As(err, &autherrs.Forbidden{}) {
+			return &Error{err.Error(), StatusForbidden, err}
+		}
+
+		return &Error{err.Error(), StatusBadRequest, err}
+	}
+	schemaVersion := fetchedClass[input.Class].Version
+
 	unlock, err := m.locks.LockSchema()
 	if err != nil {
 		return &Error{"cannot lock", StatusInternalServerError, err}
 	}
 	defer unlock()
 	validator := validation.New(m.vectorRepo.Exists, m.config, repl)
-	targetRef, reqClass, schemaVersion, err := input.validate(ctx, principal, validator, m.schemaManager)
+	targetRef, reqClass, err := input.validate(validator, fetchedClass[input.Class].Class)
 	if err != nil {
 		if errors.As(err, &ErrMultiTenancy{}) {
 			return &Error{"validate inputs", StatusUnprocessableEntity, err}
@@ -108,8 +114,8 @@ func (m *Manager) AddObjectReference(ctx context.Context, principal *models.Prin
 	if !deprecatedEndpoint {
 		ok, err := m.vectorRepo.Exists(ctx, input.Class, input.ID, repl, tenant)
 		if err != nil {
-			switch {
-			case errors.As(err, &ErrMultiTenancy{}):
+			switch err.(type) {
+			case ErrMultiTenancy:
 				return &Error{"source object", StatusUnprocessableEntity, err}
 			default:
 				return &Error{"source object", StatusInternalServerError, err}
@@ -130,7 +136,7 @@ func (m *Manager) AddObjectReference(ctx context.Context, principal *models.Prin
 
 	if shouldValidateMultiTenantRef(tenant, source, target) {
 		_, err = validateReferenceMultiTenancy(ctx, principal,
-			m.schemaManager, m.vectorRepo, source, target, tenant)
+			m.schemaManager, m.vectorRepo, source, target, tenant, fetchedClass)
 		if err != nil {
 			return &Error{"multi-tenancy violation", StatusInternalServerError, err}
 		}
@@ -172,26 +178,18 @@ type AddReferenceInput struct {
 }
 
 func (req *AddReferenceInput) validate(
-	ctx context.Context,
-	principal *models.Principal,
 	v *validation.Validator,
-	sm schemaManager,
-) (*crossref.Ref, *models.Class, uint64, error) {
+	class *models.Class,
+) (*crossref.Ref, *models.Class, error) {
 	if err := validateReferenceName(req.Class, req.Property); err != nil {
-		return nil, nil, 0, err
+		return nil, nil, err
 	}
 	ref, err := v.ValidateSingleRef(&req.Ref)
 	if err != nil {
-		return nil, nil, 0, err
-	}
-
-	vclasses, err := sm.GetCachedClass(ctx, principal, req.Class)
-	if err != nil {
-		return nil, nil, 0, err
+		return nil, nil, err
 	}
-	vclass := vclasses[req.Class]
 
-	return ref, vclass.Class, vclass.Version, validateReferenceSchema(sm, vclass.Class, req.Property)
+	return ref, class, validateReferenceSchema(class, req.Property)
 }
 
 func (req *AddReferenceInput) validateExistence(
diff --git a/usecases/objects/references_delete.go b/usecases/objects/references_delete.go
index 3b8e204d56..9ae552a2c7 100644
--- a/usecases/objects/references_delete.go
+++ b/usecases/objects/references_delete.go
@@ -154,7 +154,7 @@ func (req *DeleteReferenceInput) validate(
 		return nil, 0, err
 	}
 	vclass := vclasses[req.Class]
-	return vclass.Class, vclass.Version, validateReferenceSchema(sm, vclass.Class, req.Property)
+	return vclass.Class, vclass.Version, validateReferenceSchema(vclass.Class, req.Property)
 }
 
 // removeReference removes ref from object obj with property prop.
diff --git a/usecases/objects/references_update.go b/usecases/objects/references_update.go
index 1f7ac7fe08..7fd8eab48e 100644
--- a/usecases/objects/references_update.go
+++ b/usecases/objects/references_update.go
@@ -159,7 +159,7 @@ func (req *PutReferenceInput) validate(
 	}
 
 	vclass := vclasses[req.Class]
-	return refs, vclass.Version, validateReferenceSchema(sm, vclass.Class, req.Property)
+	return refs, vclass.Version, validateReferenceSchema(vclass.Class, req.Property)
 }
 
 func (req *PutReferenceInput) validateExistence(
@@ -186,13 +186,14 @@ func validateReferenceName(class, property string) error {
 	return nil
 }
 
-func validateReferenceSchema(sm schemaManager, c *models.Class, property string) error {
+func validateReferenceSchema(c *models.Class, property string) error {
 	prop, err := schema.GetPropertyByName(c, property)
 	if err != nil {
 		return err
 	}
 
-	dt, err := schema.FindPropertyDataTypeWithRefs(sm.ReadOnlyClass, prop.DataType, false, "")
+	classGetterFunc := func(string) *models.Class { return c }
+	dt, err := schema.FindPropertyDataTypeWithRefs(classGetterFunc, prop.DataType, false, "")
 	if err != nil {
 		return err
 	}
diff --git a/usecases/objects/validation/phone_numbers.go b/usecases/objects/validation/phone_numbers.go
index 0cd11b464f..a985089122 100644
--- a/usecases/objects/validation/phone_numbers.go
+++ b/usecases/objects/validation/phone_numbers.go
@@ -12,12 +12,10 @@
 package validation
 
 import (
-	"errors"
 	"fmt"
 	"strings"
 
 	"github.com/nyaruka/phonenumbers"
-
 	"github.com/weaviate/weaviate/entities/models"
 )
 
@@ -25,11 +23,11 @@ func parsePhoneNumber(input, defaultCountry string) (*models.PhoneNumber, error)
 	defaultCountry = strings.ToUpper(defaultCountry)
 	num, err := phonenumbers.Parse(input, defaultCountry)
 	if err != nil {
-		switch {
-		case errors.Is(err, phonenumbers.ErrInvalidCountryCode):
+		switch err {
+		case phonenumbers.ErrInvalidCountryCode:
 			return nil, fmt.Errorf("invalid phone number: invalid or missing defaultCountry - this field is optional if the specified number is in the international format, but required if the number is in national format, use ISO 3166-1 alpha-2")
 		default:
-			return nil, fmt.Errorf("invalid phone number: %w", err)
+			return nil, fmt.Errorf("invalid phone number: %v", err)
 		}
 	}
 
diff --git a/usecases/objects/validation/properties_validation.go b/usecases/objects/validation/properties_validation.go
index 086ddeadfd..85706a20cf 100644
--- a/usecases/objects/validation/properties_validation.go
+++ b/usecases/objects/validation/properties_validation.go
@@ -54,7 +54,7 @@ func (v *Validator) properties(ctx context.Context, class *models.Class,
 	if vectorWeights != nil {
 		res, err := v.validateVectorWeights(vectorWeights)
 		if err != nil {
-			return fmt.Errorf("vector weights: %w", err)
+			return fmt.Errorf("vector weights: %v", err)
 		}
 
 		vectorWeights = res
@@ -250,94 +250,94 @@ func (v *Validator) extractAndValidateProperty(ctx context.Context, propertyName
 	case schema.DataTypeCRef:
 		data, err = v.cRef(ctx, propertyName, pv, className, tenant)
 		if err != nil {
-			return nil, fmt.Errorf("invalid cref: %w", err)
+			return nil, fmt.Errorf("invalid cref: %s", err)
 		}
 	case schema.DataTypeText:
 		data, err = stringVal(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid text property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid text property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypeUUID:
 		data, err = uuidVal(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid uuid property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid uuid property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypeInt:
 		data, err = intVal(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid integer property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid integer property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypeNumber:
 		data, err = numberVal(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid number property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid number property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypeBoolean:
 		data, err = boolVal(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid boolean property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid boolean property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypeDate:
 		data, err = dateVal(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid date property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid date property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypeGeoCoordinates:
 		data, err = geoCoordinates(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid geoCoordinates property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid geoCoordinates property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypePhoneNumber:
 		data, err = phoneNumber(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid phoneNumber property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid phoneNumber property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypeBlob:
 		data, err = blobVal(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid blob property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid blob property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypeTextArray:
 		data, err = stringArrayVal(pv, "text")
 		if err != nil {
-			return nil, fmt.Errorf("invalid text array property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid text array property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypeIntArray:
 		data, err = intArrayVal(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid integer array property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid integer array property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypeNumberArray:
 		data, err = numberArrayVal(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid number array property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid number array property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypeBooleanArray:
 		data, err = boolArrayVal(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid boolean array property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid boolean array property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypeDateArray:
 		data, err = dateArrayVal(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid date array property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid date array property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	case schema.DataTypeUUIDArray:
 		data, err = uuidArrayVal(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid uuid array property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid uuid array property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	// deprecated string
 	case schema.DataTypeString:
 		data, err = stringVal(pv)
 		if err != nil {
-			return nil, fmt.Errorf("invalid string property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid string property '%s' on class '%s': %s", propertyName, className, err)
 		}
 	// deprecated string
 	case schema.DataTypeStringArray:
 		data, err = stringArrayVal(pv, "string")
 		if err != nil {
-			return nil, fmt.Errorf("invalid string array property '%s' on class '%s': %w", propertyName, className, err)
+			return nil, fmt.Errorf("invalid string array property '%s' on class '%s': %s", propertyName, className, err)
 		}
 
 	default:
@@ -486,12 +486,12 @@ func geoCoordinates(input interface{}) (*models.GeoCoordinates, error) {
 
 	lonFloat, err := parseCoordinate(lon)
 	if err != nil {
-		return nil, fmt.Errorf("invalid longitude: %w", err)
+		return nil, fmt.Errorf("invalid longitude: %s", err)
 	}
 
 	latFloat, err := parseCoordinate(lat)
 	if err != nil {
-		return nil, fmt.Errorf("invalid latitude: %w", err)
+		return nil, fmt.Errorf("invalid latitude: %s", err)
 	}
 
 	return &models.GeoCoordinates{
@@ -539,7 +539,7 @@ func parseCoordinate(raw interface{}) (float64, error) {
 	case json.Number:
 		asFloat, err := v.Float64()
 		if err != nil {
-			return 0, fmt.Errorf("cannot interpret as float: %w", err)
+			return 0, fmt.Errorf("cannot interpret as float: %s", err)
 		}
 		return asFloat, nil
 	case float64:
@@ -589,7 +589,7 @@ func (v *Validator) parseAndValidateSingleRef(ctx context.Context, propertyName
 
 	ref, err := crossref.Parse(pvcr["beacon"].(string))
 	if err != nil {
-		return nil, fmt.Errorf("invalid reference: %w", err)
+		return nil, fmt.Errorf("invalid reference: %s", err)
 	}
 	errVal := fmt.Sprintf("'cref' %s:%s", className, propertyName)
 	ref, err = v.ValidateSingleRef(ref.SingleRef())
diff --git a/usecases/replica/repairer.go b/usecases/replica/repairer.go
index ec056fe2e0..a698164e03 100644
--- a/usecases/replica/repairer.go
+++ b/usecases/replica/repairer.go
@@ -122,7 +122,7 @@ func (r *repairer) repairOne(ctx context.Context,
 			return nil, fmt.Errorf("get most recent object from %s: %w", winner.sender, err)
 		}
 		if updates.UpdateTime() != lastUTime {
-			return nil, fmt.Errorf("fetch new state from %s: %w, %w", winner.sender, errConflictObjectChanged, err)
+			return nil, fmt.Errorf("fetch new state from %s: %w, %v", winner.sender, errConflictObjectChanged, err)
 		}
 	}
 
@@ -251,7 +251,7 @@ func (r *repairer) repairExist(ctx context.Context,
 		return false, fmt.Errorf("get most recent object from %s: %w", winner.sender, err)
 	}
 	if resp.UpdateTime() != lastUTime {
-		return false, fmt.Errorf("fetch new state from %s: %w, %w", winner.sender, errConflictObjectChanged, err)
+		return false, fmt.Errorf("fetch new state from %s: %w, %v", winner.sender, errConflictObjectChanged, err)
 	}
 
 	gr, ctx := enterrors.NewErrorGroupWithContextWrapper(r.logger, ctx)
diff --git a/usecases/replica/replicator.go b/usecases/replica/replicator.go
index 60de8f4e7d..472922cf81 100644
--- a/usecases/replica/replicator.go
+++ b/usecases/replica/replicator.go
@@ -13,14 +13,12 @@ package replica
 
 import (
 	"context"
-	"errors"
 	"fmt"
 	"sync/atomic"
 	"time"
 
 	"github.com/go-openapi/strfmt"
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/entities/storobj"
 	"github.com/weaviate/weaviate/usecases/objects"
 )
@@ -154,8 +152,8 @@ func (r *Replicator) MergeObject(ctx context.Context,
 	if err != nil {
 		r.log.WithField("op", "merge").WithField("class", r.class).
 			WithField("shard", shard).WithField("uuid", doc.ID).Error(err)
-		var replicaErr *Error
-		if errors.As(err, &replicaErr) && replicaErr != nil && replicaErr.Code == StatusObjectNotFound {
+		replicaErr, ok := err.(*Error)
+		if ok && replicaErr != nil && replicaErr.Code == StatusObjectNotFound {
 			return objects.NewErrDirtyWriteOfDeletedObject(replicaErr)
 		}
 	}
diff --git a/usecases/schema/class.go b/usecases/schema/class.go
index fd56501e0c..f435d7a97f 100644
--- a/usecases/schema/class.go
+++ b/usecases/schema/class.go
@@ -19,16 +19,16 @@ import (
 	"reflect"
 	"strings"
 
+	entcfg "github.com/weaviate/weaviate/entities/config"
+	"github.com/weaviate/weaviate/entities/replication"
+
 	"github.com/pkg/errors"
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/sirupsen/logrus"
-
 	"github.com/weaviate/weaviate/adapters/repos/db/inverted/stopwords"
 	"github.com/weaviate/weaviate/entities/backup"
 	"github.com/weaviate/weaviate/entities/classcache"
-	entcfg "github.com/weaviate/weaviate/entities/config"
 	"github.com/weaviate/weaviate/entities/models"
-	"github.com/weaviate/weaviate/entities/replication"
 	"github.com/weaviate/weaviate/entities/schema"
 	"github.com/weaviate/weaviate/entities/vectorindex"
 	"github.com/weaviate/weaviate/entities/versioned"
@@ -572,7 +572,7 @@ func (h *Handler) validateProperty(
 		propertyDataType, err := schema.FindPropertyDataTypeWithRefsAndAuth(classGetterWithAuth, property.DataType,
 			relaxCrossRefValidation, schema.ClassName(class.Class))
 		if err != nil {
-			return fmt.Errorf("property '%s': invalid dataType: %v: %w", property.Name, property.DataType, err)
+			return errors.Wrapf(err, "property '%s': invalid dataType: %v", property.Name, property.DataType)
 		}
 
 		if propertyDataType.IsNested() {
diff --git a/usecases/traverser/aggregate_type_inspector.go b/usecases/traverser/aggregate_type_inspector.go
index 4d141b4097..fdcf206f5a 100644
--- a/usecases/traverser/aggregate_type_inspector.go
+++ b/usecases/traverser/aggregate_type_inspector.go
@@ -52,7 +52,7 @@ func (i *typeInspector) WithTypes(res *aggregation.Result, params aggregation.Pa
 
 		err = i.extendResWithType(res, prop.Name.String(), schemaProp.DataType)
 		if err != nil {
-			return nil, fmt.Errorf("with types: prop %s: %w", prop.Name, err)
+			return nil, fmt.Errorf("with types: prop %s: %v", prop.Name, err)
 		}
 	}
 
diff --git a/usecases/traverser/grouper/grouper.go b/usecases/traverser/grouper/grouper.go
index db9b4917c5..8d4dc4932a 100644
--- a/usecases/traverser/grouper/grouper.go
+++ b/usecases/traverser/grouper/grouper.go
@@ -133,7 +133,7 @@ func (gs groups) flattenMerge() ([]search.Result, error) {
 	for i, group := range gs.Elements {
 		merged, err := group.flattenMerge()
 		if err != nil {
-			return nil, fmt.Errorf("group %d: %w", i, err)
+			return nil, fmt.Errorf("group %d: %v", i, err)
 		}
 
 		out[i] = merged
diff --git a/usecases/traverser/grouper/merge_group.go b/usecases/traverser/grouper/merge_group.go
index 51f0f53927..8e8c59218e 100644
--- a/usecases/traverser/grouper/merge_group.go
+++ b/usecases/traverser/grouper/merge_group.go
@@ -42,12 +42,12 @@ func (g group) flattenMerge() (search.Result, error) {
 	values := g.makeValueGroups()
 	merged, err := mergeValueGroups(values)
 	if err != nil {
-		return search.Result{}, fmt.Errorf("merge values: %w", err)
+		return search.Result{}, fmt.Errorf("merge values: %v", err)
 	}
 
 	vector, err := g.mergeVectors()
 	if err != nil {
-		return search.Result{}, fmt.Errorf("merge vectors: %w", err)
+		return search.Result{}, fmt.Errorf("merge vectors: %v", err)
 	}
 
 	className := g.mergeGetClassName()
@@ -151,7 +151,7 @@ func mergeValueGroups(props map[string]valueGroup) (map[string]interface{}, erro
 			err = fmt.Errorf("unrecognized value type")
 		}
 		if err != nil {
-			return nil, fmt.Errorf("prop '%s': %w", propName, err)
+			return nil, fmt.Errorf("prop '%s': %v", propName, err)
 		}
 
 		mergedProps[propName] = res
diff --git a/usecases/traverser/traverser_schema_search_params.go b/usecases/traverser/traverser_schema_search_params.go
index 162611a58a..fbdb14ad9d 100644
--- a/usecases/traverser/traverser_schema_search_params.go
+++ b/usecases/traverser/traverser_schema_search_params.go
@@ -48,7 +48,7 @@ func (p SearchParams) Validate() error {
 	}
 
 	if err := p.validateCertaintyOrWeight(p.Certainty); err != nil {
-		return fmt.Errorf("invalid Certainty: %w", err)
+		return fmt.Errorf("invalid Certainty: %s", err)
 	}
 
 	if p.SearchType != SearchTypeClass && p.SearchType != SearchTypeProperty {
diff --git a/usecases/vectorizer/distance.go b/usecases/vectorizer/distance.go
index 8624d8e4ed..3035a8576f 100644
--- a/usecases/vectorizer/distance.go
+++ b/usecases/vectorizer/distance.go
@@ -21,7 +21,7 @@ import (
 func NormalizedDistance(a, b []float32) (float32, error) {
 	sim, err := cosineSim(a, b)
 	if err != nil {
-		return 1, fmt.Errorf("normalized distance: %w", err)
+		return 1, fmt.Errorf("normalized distance: %v", err)
 	}
 
 	return (1 - sim) / 2, nil


Test patch:
diff --git a/adapters/handlers/rest/filterext/parse_test.go b/adapters/handlers/rest/filterext/parse_test.go
index ab5767fea7..54e933ed39 100644
--- a/adapters/handlers/rest/filterext/parse_test.go
+++ b/adapters/handlers/rest/filterext/parse_test.go
@@ -16,7 +16,6 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
-
 	"github.com/weaviate/weaviate/entities/filters"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/entities/schema"
@@ -287,7 +286,7 @@ func Test_ExtractFlatFilters(t *testing.T) {
 		for _, test := range tests {
 			t.Run(test.name, func(t *testing.T) {
 				filter, err := Parse(test.input, "Todo")
-				assert.ErrorAs(t, err, &test.expectedErr)
+				assert.Equal(t, test.expectedErr, err)
 				assert.Equal(t, test.expectedFilter, filter)
 			})
 		}
diff --git a/adapters/repos/db/lsmkv/bucket_test.go b/adapters/repos/db/lsmkv/bucket_test.go
index 3da96bed8b..c3fc2559f3 100644
--- a/adapters/repos/db/lsmkv/bucket_test.go
+++ b/adapters/repos/db/lsmkv/bucket_test.go
@@ -20,7 +20,6 @@ import (
 	"github.com/sirupsen/logrus/hooks/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/entities/cyclemanager"
 )
 
diff --git a/adapters/repos/db/vector/hnsw/benchmark_test.go b/adapters/repos/db/vector/hnsw/benchmark_test.go
index 6ea1bd230f..7b829ba48a 100644
--- a/adapters/repos/db/vector/hnsw/benchmark_test.go
+++ b/adapters/repos/db/vector/hnsw/benchmark_test.go
@@ -25,12 +25,12 @@ import (
 	"testing"
 	"time"
 
-	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus/hooks/test"
-	"github.com/stretchr/testify/require"
-	"gopkg.in/yaml.v2"
 
+	"github.com/pkg/errors"
+	"github.com/stretchr/testify/require"
 	"github.com/weaviate/weaviate/adapters/repos/db/vector/compressionhelpers"
+	"gopkg.in/yaml.v2"
 )
 
 var download = flag.Bool("download", false, "download datasets if not found locally")
@@ -254,7 +254,7 @@ func readBigAnnDataset(t testing.TB, file string, maxObjects int) [][]float32 {
 
 	for i := 0; i < n; i++ {
 		_, err = f.Read(vectorBytes)
-		if errors.Is(err, io.EOF) {
+		if err == io.EOF {
 			break
 		}
 		require.NoError(t, err)
diff --git a/adapters/repos/db/vector/hnsw/hnsw_stress_test.go b/adapters/repos/db/vector/hnsw/hnsw_stress_test.go
index d39bac6140..3244e1db0f 100644
--- a/adapters/repos/db/vector/hnsw/hnsw_stress_test.go
+++ b/adapters/repos/db/vector/hnsw/hnsw_stress_test.go
@@ -25,15 +25,16 @@ import (
 	"testing"
 	"time"
 
-	"github.com/pkg/errors"
-	"github.com/sirupsen/logrus"
-	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/adapters/repos/db/vector/hnsw/distancer"
 	"github.com/weaviate/weaviate/adapters/repos/db/vector/testinghelpers"
 	"github.com/weaviate/weaviate/entities/cyclemanager"
-	enterrors "github.com/weaviate/weaviate/entities/errors"
 	ent "github.com/weaviate/weaviate/entities/vectorindex/hnsw"
+
+	"github.com/sirupsen/logrus"
+	enterrors "github.com/weaviate/weaviate/entities/errors"
+
+	"github.com/pkg/errors"
+	"github.com/stretchr/testify/require"
 )
 
 const (
@@ -428,7 +429,7 @@ func readSiftFloat(file string, maxObjects int) [][]float32 {
 	vectorBytes := make([]byte, bytesPerF+vectorSize*bytesPerF)
 	for i := 0; i >= 0; i++ {
 		_, err = f.Read(vectorBytes)
-		if errors.Is(err, io.EOF) {
+		if err == io.EOF {
 			break
 		} else if err != nil {
 			panic(err)
diff --git a/adapters/repos/db/vector/testinghelpers/helpers.go b/adapters/repos/db/vector/testinghelpers/helpers.go
index 03f3497662..9c275aad2c 100644
--- a/adapters/repos/db/vector/testinghelpers/helpers.go
+++ b/adapters/repos/db/vector/testinghelpers/helpers.go
@@ -23,11 +23,11 @@ import (
 	"testing"
 	"time"
 
-	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
+
+	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus/hooks/test"
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/adapters/repos/db/lsmkv"
 	"github.com/weaviate/weaviate/adapters/repos/db/vector/compressionhelpers"
 	"github.com/weaviate/weaviate/adapters/repos/db/vector/hnsw/distancer"
@@ -83,7 +83,7 @@ func readSiftFloat(file string, maxObjects int, vectorLengthFloat int) [][]float
 	vectorBytes := make([]byte, bytesPerF+vectorLengthFloat*bytesPerF)
 	for i := 0; i >= 0; i++ {
 		_, err = f.Read(vectorBytes)
-		if errors.Is(err, io.EOF) {
+		if err == io.EOF {
 			break
 		} else if err != nil {
 			panic(err)
diff --git a/test/acceptance/actions/object_test.go b/test/acceptance/actions/object_test.go
index c1c297506e..6901e0d099 100644
--- a/test/acceptance/actions/object_test.go
+++ b/test/acceptance/actions/object_test.go
@@ -21,7 +21,6 @@ import (
 	"github.com/go-openapi/strfmt"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/client/batch"
 	"github.com/weaviate/weaviate/client/objects"
 	"github.com/weaviate/weaviate/entities/models"
@@ -460,16 +459,14 @@ func TestPostReference(t *testing.T) {
 
 	params.WithPropertyName("unknown")
 	_, err = helper.Client(t).Objects.ObjectsClassReferencesCreate(params, nil)
-	var targetErr *objects.ObjectsClassReferencesCreateUnprocessableEntity
-	if !errors.As(err, &targetErr) {
+	if _, ok := err.(*objects.ObjectsClassReferencesCreateUnprocessableEntity); !ok {
 		t.Errorf("error type expected: %T, got %T", objects.ObjectsClassReferencesCreateUnprocessableEntity{}, err)
 	}
 
 	params.WithPropertyName("friend")
 	params.WithID("e7cd261a-0000-0000-0000-d7b8e7b5c9ea")
 	_, err = helper.Client(t).Objects.ObjectsClassReferencesCreate(params, nil)
-	var targetNotFoundErr *objects.ObjectsClassReferencesCreateNotFound
-	if !errors.As(err, &targetNotFoundErr) {
+	if _, ok := err.(*objects.ObjectsClassReferencesCreateNotFound); !ok {
 		t.Errorf("error type expected: %T, got %T", objects.ObjectsClassReferencesCreateNotFound{}, err)
 	}
 }
@@ -563,16 +560,14 @@ func TestPutReferences(t *testing.T) {
 
 	params.WithPropertyName("unknown")
 	_, err = helper.Client(t).Objects.ObjectsClassReferencesPut(params, nil)
-	var expectedErr *objects.ObjectsClassReferencesPutUnprocessableEntity
-	if !errors.As(err, &expectedErr) {
+	if _, ok := err.(*objects.ObjectsClassReferencesPutUnprocessableEntity); !ok {
 		t.Errorf("error type expected: %T, got %T", objects.ObjectsClassReferencesPutUnprocessableEntity{}, err)
 	}
 	params.WithPropertyName("friend")
 
 	params.WithID("e7cd261a-0000-0000-0000-d7b8e7b5c9ea")
 	_, err = helper.Client(t).Objects.ObjectsClassReferencesPut(params, nil)
-	var expectedRefErr *objects.ObjectsClassReferencesPutNotFound
-	if !errors.As(err, &expectedRefErr) {
+	if _, ok := err.(*objects.ObjectsClassReferencesPutNotFound); !ok {
 		t.Errorf("error type expected: %T, got %T", objects.ObjectsClassReferencesPutNotFound{}, err)
 	}
 	params.WithID(uuid)
@@ -589,8 +584,7 @@ func TestPutReferences(t *testing.T) {
 	// bad request since body is required
 	params.WithID(uuid).WithBody(nil).WithPropertyName("friend")
 	_, err = helper.Client(t).Objects.ObjectsClassReferencesPut(params, nil)
-	var expectedErr2 *objects.ObjectsClassReferencesPutUnprocessableEntity
-	if !errors.As(err, &expectedErr2) {
+	if _, ok := err.(*objects.ObjectsClassReferencesPutUnprocessableEntity); !ok {
 		t.Errorf("error type expected: %T, got %T", objects.ObjectsClassReferencesPutUnprocessableEntity{}, err)
 	}
 }
@@ -699,8 +693,7 @@ func TestDeleteReference(t *testing.T) {
 	// property is not part of the schema
 	params.WithPropertyName("unknown")
 	_, err = helper.Client(t).Objects.ObjectsClassReferencesDelete(params, nil)
-	var deleteUnprocessableEntityErr *objects.ObjectsClassReferencesDeleteUnprocessableEntity
-	if !errors.As(err, &deleteUnprocessableEntityErr) {
+	if _, ok := err.(*objects.ObjectsClassReferencesDeleteUnprocessableEntity); !ok {
 		t.Errorf("error type expected: %T, got %T", objects.ObjectsClassReferencesDeleteUnprocessableEntity{}, err)
 	}
 	params.WithPropertyName("friend")
@@ -708,17 +701,16 @@ func TestDeleteReference(t *testing.T) {
 	// This ID doesn't exist
 	params.WithID("e7cd261a-0000-0000-0000-d7b8e7b5c9ea")
 	_, err = helper.Client(t).Objects.ObjectsClassReferencesDelete(params, nil)
-	var deleteNotFoundErr *objects.ObjectsClassReferencesDeleteNotFound
-	if !errors.As(err, &deleteNotFoundErr) {
-		t.Errorf("error type expected: %T, got %T", *deleteNotFoundErr, err)
+	if _, ok := err.(*objects.ObjectsClassReferencesDeleteNotFound); !ok {
+		t.Errorf("error type expected: %T, got %T", objects.ObjectsClassReferencesDeleteNotFound{}, err)
 	}
 	params.WithID(uuid)
 
 	// bad request since body is required
 	params.WithID(uuid).WithBody(nil).WithPropertyName("friend")
 	_, err = helper.Client(t).Objects.ObjectsClassReferencesDelete(params, nil)
-	if !errors.As(err, &deleteUnprocessableEntityErr) {
-		t.Errorf("error type expected: %T, got %T", *deleteUnprocessableEntityErr, err)
+	if _, ok := err.(*objects.ObjectsClassReferencesDeleteUnprocessableEntity); !ok {
+		t.Errorf("error type expected: %T, got %T", objects.ObjectsClassReferencesDeleteUnprocessableEntity{}, err)
 	}
 }
 
@@ -782,8 +774,7 @@ func TestQuery(t *testing.T) {
 	unknown_cls := "unknow"
 	listParams.Class = &unknown_cls
 	_, err = helper.Client(t).Objects.ObjectsList(listParams, nil)
-	var customErr *objects.ObjectsListNotFound
-	if !errors.As(err, &customErr) {
-		t.Errorf("error type expected: %T, got %T", *customErr, err)
+	if _, ok := err.(*objects.ObjectsListNotFound); !ok {
+		t.Errorf("error type expected: %T, got %T", objects.ObjectsListNotFound{}, err)
 	}
 }
diff --git a/test/acceptance/authz/auto_tenancy_test.go b/test/acceptance/authz/auto_tenancy_test.go
index 8e1948a1ef..f3ff6df686 100644
--- a/test/acceptance/authz/auto_tenancy_test.go
+++ b/test/acceptance/authz/auto_tenancy_test.go
@@ -13,15 +13,10 @@ package authz
 
 import (
 	"context"
-	"errors"
 	"fmt"
 	"testing"
 
 	"github.com/stretchr/testify/require"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/metadata"
-	"google.golang.org/grpc/status"
-
 	"github.com/weaviate/weaviate/client/authz"
 	"github.com/weaviate/weaviate/client/objects"
 	"github.com/weaviate/weaviate/entities/models"
@@ -29,6 +24,9 @@ import (
 	"github.com/weaviate/weaviate/test/helper"
 	"github.com/weaviate/weaviate/test/helper/sample-schema/articles"
 	"github.com/weaviate/weaviate/usecases/auth/authorization"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/grpc/status"
 )
 
 func TestAuthzAutoTenantActivation(t *testing.T) {
@@ -89,8 +87,8 @@ func TestAuthzAutoTenantActivation(t *testing.T) {
 	t.Run("fail with 403 when trying to create an object in an inactive tenant due to lacking authorization.UpdateTenants for autoTenantActivation", func(t *testing.T) {
 		_, err := createObject(t, obj, customKey)
 		require.NotNil(t, err)
-		var parsed *objects.ObjectsCreateForbidden
-		if !errors.As(err, &parsed) {
+		parsed, forbidden := err.(*objects.ObjectsCreateForbidden)
+		if !forbidden {
 			helper.AssertRequestOk(t, nil, err, nil)
 		}
 		require.Contains(t, parsed.Payload.Error[0].Message, "forbidden")
@@ -99,8 +97,8 @@ func TestAuthzAutoTenantActivation(t *testing.T) {
 	t.Run("fail with 403 when trying to read an object in an inactive tenant due to lacking authorization.UpdateTenants for autoTenantActivation", func(t *testing.T) {
 		_, err := getObject(t, obj2.Class, obj2.ID, &obj2.Tenant, customKey)
 		require.NotNil(t, err)
-		var parsed *objects.ObjectsClassGetForbidden
-		if !errors.As(err, &parsed) {
+		parsed, forbidden := err.(*objects.ObjectsClassGetForbidden)
+		if !forbidden {
 			helper.AssertRequestOk(t, nil, err, nil)
 		}
 		require.Contains(t, parsed.Payload.Error[0].Message, "forbidden")
@@ -109,8 +107,8 @@ func TestAuthzAutoTenantActivation(t *testing.T) {
 	t.Run("fail with 403 when trying to update an object in an inactive tenant due to lacking authorization.UpdateTenants for autoTenantActivation", func(t *testing.T) {
 		_, err := updateObject(t, obj, customKey)
 		require.NotNil(t, err)
-		var parsed *objects.ObjectsClassPatchForbidden
-		if !errors.As(err, &parsed) {
+		parsed, forbidden := err.(*objects.ObjectsClassPatchForbidden)
+		if !forbidden {
 			helper.AssertRequestOk(t, nil, err, nil)
 		}
 		require.Contains(t, parsed.Payload.Error[0].Message, "forbidden")
@@ -119,8 +117,8 @@ func TestAuthzAutoTenantActivation(t *testing.T) {
 	t.Run("fail with 403 when trying to delete an object in an inactive tenant due to lacking authorization.UpdateTenants for autoTenantActivation", func(t *testing.T) {
 		_, err := deleteObject(t, obj.Class, obj.ID, &obj.Tenant, customKey)
 		require.NotNil(t, err)
-		var parsed *objects.ObjectsClassDeleteForbidden
-		if !errors.As(err, &parsed) {
+		parsed, forbidden := err.(*objects.ObjectsClassDeleteForbidden)
+		if !forbidden {
 			helper.AssertRequestOk(t, nil, err, nil)
 		}
 		require.Contains(t, parsed.Payload.Error[0].Message, "forbidden")
@@ -261,8 +259,8 @@ func TestAuthzAutoTenantCreation(t *testing.T) {
 	t.Run("fail with 403 when trying to create an object in a non-existent tenant due to lacking authorization.CreateCollections for autoTenantCreation", func(t *testing.T) {
 		err := helper.CreateObjectAuth(t, obj, customKey)
 		require.NotNil(t, err)
-		var parsed *objects.ObjectsCreateForbidden
-		require.True(t, errors.As(err, &parsed))
+		parsed, forbidden := err.(*objects.ObjectsCreateForbidden)
+		require.True(t, forbidden)
 		require.Contains(t, parsed.Payload.Error[0].Message, "forbidden")
 	})
 
diff --git a/test/acceptance/authz/backups_test.go b/test/acceptance/authz/backups_test.go
index a68a102dde..888e7bd682 100644
--- a/test/acceptance/authz/backups_test.go
+++ b/test/acceptance/authz/backups_test.go
@@ -19,7 +19,6 @@ import (
 	"time"
 
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/client/backups"
 	"github.com/weaviate/weaviate/entities/backup"
 	"github.com/weaviate/weaviate/entities/models"
@@ -94,24 +93,24 @@ func TestAuthZBackupsManageJourney(t *testing.T) {
 		fmt.Println(roles)
 		_, err := helper.CreateBackupWithAuthz(t, helper.DefaultBackupConfig(), clsA.Class, backend, backupID, helper.CreateAuth(viewerKey))
 		require.NotNil(t, err)
-		var parsed *backups.BackupsCreateForbidden
-		require.True(t, errors.As(err, &parsed))
+		parsed, forbidden := err.(*backups.BackupsCreateForbidden)
+		require.True(t, forbidden)
 		require.Contains(t, parsed.Payload.Error[0].Message, "forbidden")
 	})
 
 	t.Run("fail to create a backup due to missing manage_backups action", func(t *testing.T) {
 		_, err := helper.CreateBackupWithAuthz(t, helper.DefaultBackupConfig(), clsA.Class, backend, backupID, helper.CreateAuth(customKey))
 		require.NotNil(t, err)
-		var parsed *backups.BackupsCreateForbidden
-		require.True(t, errors.As(err, &parsed))
+		parsed, forbidden := err.(*backups.BackupsCreateForbidden)
+		require.True(t, forbidden)
 		require.Contains(t, parsed.Payload.Error[0].Message, "forbidden")
 	})
 
 	t.Run("fail to cancel a backup due to missing manage_backups action", func(t *testing.T) {
 		err := helper.CancelBackupWithAuthz(t, backend, backupID, helper.CreateAuth(customKey))
 		require.NotNil(t, err)
-		var parsed *backups.BackupsCancelForbidden
-		require.True(t, errors.As(err, &parsed))
+		parsed, forbidden := err.(*backups.BackupsCancelForbidden)
+		require.True(t, forbidden)
 		require.Contains(t, parsed.Payload.Error[0].Message, "forbidden")
 	})
 
diff --git a/test/acceptance/authz/batch_refs_test.go b/test/acceptance/authz/batch_refs_test.go
new file mode 100644
index 0000000000..943052f5e6
--- /dev/null
+++ b/test/acceptance/authz/batch_refs_test.go
@@ -0,0 +1,89 @@
+//                           _       _
+// __      _____  __ ___   ___  __ _| |_ ___
+// \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
+//  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
+//   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
+//
+//  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
+//
+//  CONTACT: hello@weaviate.io
+//
+
+package authz
+
+import (
+	"testing"
+
+	"github.com/go-openapi/strfmt"
+	"github.com/stretchr/testify/require"
+	"github.com/weaviate/weaviate/client/batch"
+	"github.com/weaviate/weaviate/entities/models"
+	"github.com/weaviate/weaviate/entities/schema"
+	"github.com/weaviate/weaviate/test/helper"
+)
+
+func TestAuthZBatchRefAuthZCalls(t *testing.T) {
+	adminUser := "admin-user"
+	adminKey := "admin-key"
+	adminAuth := helper.CreateAuth(adminKey)
+
+	compose, down := composeUp(t, map[string]string{adminUser: adminKey}, map[string]string{}, nil)
+	defer down()
+
+	containers := compose.Containers()
+	require.Len(t, containers, 1) // started only one node
+
+	// add classes with object
+	className1 := "AuthZBatchObjREST1"
+	className2 := "AuthZBatchObjREST2"
+	deleteObjectClass(t, className1, adminAuth)
+	deleteObjectClass(t, className2, adminAuth)
+	defer deleteObjectClass(t, className1, adminAuth)
+	defer deleteObjectClass(t, className2, adminAuth)
+
+	c1 := &models.Class{
+		Class: className1,
+		Properties: []*models.Property{
+			{
+				Name:     "ref",
+				DataType: []string{className2},
+			},
+		},
+	}
+	c2 := &models.Class{
+		Class: className2,
+		Properties: []*models.Property{
+			{
+				Name:     "prop2",
+				DataType: schema.DataTypeText.PropString(),
+			},
+		},
+	}
+	require.Nil(t, createClass(t, c2, adminAuth))
+	require.Nil(t, createClass(t, c1, adminAuth))
+
+	// add an object to each class
+	helper.CreateObjectAuth(t, &models.Object{ID: UUID1, Class: className1}, adminKey)
+	helper.CreateObjectAuth(t, &models.Object{ID: UUID1, Class: className2}, adminKey)
+
+	ls := newLogScanner(containers[0].Container())
+	ls.GetAuthzLogs(t) // startup and object class creation logs that are irrelevant
+
+	from := beaconStart + className1 + "/" + UUID1.String() + "/ref"
+	to := beaconStart + UUID1
+
+	var refs []*models.BatchReference
+	for i := 0; i < 30; i++ {
+		refs = append(refs, &models.BatchReference{
+			From: strfmt.URI(from), To: strfmt.URI(to),
+		})
+	}
+
+	params := batch.NewBatchReferencesCreateParams().WithBody(refs)
+	res, err := helper.Client(t).Batch.BatchReferencesCreate(params, adminAuth)
+	require.NoError(t, err)
+	require.NotNil(t, res.Payload)
+
+	authZlogs := ls.GetAuthzLogs(t)
+	require.LessOrEqual(t, len(authZlogs), 4)
+}
diff --git a/test/acceptance/authz/gql_simple_test.go b/test/acceptance/authz/gql_simple_test.go
index f05aa46408..36fa9d0db6 100644
--- a/test/acceptance/authz/gql_simple_test.go
+++ b/test/acceptance/authz/gql_simple_test.go
@@ -13,13 +13,11 @@ package authz
 
 import (
 	"context"
-	"errors"
 	"fmt"
 	"testing"
 	"time"
 
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/client/authz"
 	gql "github.com/weaviate/weaviate/client/graphql"
 	"github.com/weaviate/weaviate/entities/models"
@@ -84,23 +82,23 @@ func TestAuthZGraphQLSingleTenancy(t *testing.T) {
 	t.Run("fail with 403 to query with Get due to lack of read all collections permission", func(t *testing.T) {
 		_, err := queryGQL(t, "{ Get { Books { title } } }", customKey)
 		require.NotNil(t, err)
-		var cErr *gql.GraphqlPostForbidden
-		require.True(t, errors.As(err, &cErr))
+		_, forbidden := err.(*gql.GraphqlPostForbidden)
+		require.True(t, forbidden)
 	})
 
 	t.Run("fail with 403 to query with Aggregate due to lack of read all collections permission", func(t *testing.T) {
 		_, err := queryGQL(t, "{ Aggregate { Books { meta { count } } } }", customKey)
 		require.NotNil(t, err)
-		var cErr *gql.GraphqlPostForbidden
-		require.True(t, errors.As(err, &cErr))
+		_, forbidden := err.(*gql.GraphqlPostForbidden)
+		require.True(t, forbidden)
 	})
 
 	t.Run("fail with 403 to query with Explore due to lack of read all collections permission", func(t *testing.T) {
 		query := fmt.Sprintf("{ Explore(nearObject:{id:%s}) { className }}", books.Objects()[0].ID)
 		_, err = queryGQL(t, query, customKey)
 		require.NotNil(t, err)
-		var cErr *gql.GraphqlPostForbidden
-		require.True(t, errors.As(err, &cErr))
+		_, forbidden := err.(*gql.GraphqlPostForbidden)
+		require.True(t, forbidden)
 	})
 
 	t.Run("add the read all collections permission to the role", func(t *testing.T) {
@@ -235,16 +233,16 @@ func TestAuthZGraphQLMultiTenancy(t *testing.T) {
 		query := fmt.Sprintf(`{ Get { %s(tenant:"%s") { title } } }`, class.Class, customUser)
 		_, err := queryGQL(t, query, customKey)
 		require.NotNil(t, err)
-		var cErr *gql.GraphqlPostForbidden
-		require.True(t, errors.As(err, &cErr))
+		_, forbidden := err.(*gql.GraphqlPostForbidden)
+		require.True(t, forbidden)
 	})
 
 	t.Run("fail with 403 to query with Aggregate due to lack of read all collections permission", func(t *testing.T) {
 		query := fmt.Sprintf(`{ Aggregate { %s(tenant:"%s") { meta { count } } } }`, class.Class, customUser)
 		_, err = queryGQL(t, query, customKey)
 		require.NotNil(t, err)
-		var cErr *gql.GraphqlPostForbidden
-		require.True(t, errors.As(err, &cErr))
+		_, forbidden := err.(*gql.GraphqlPostForbidden)
+		require.True(t, forbidden)
 	})
 
 	t.Run("add the read all collections permission to the role", func(t *testing.T) {
diff --git a/test/acceptance/authz/helper.go b/test/acceptance/authz/helper.go
index b24d24352a..36f03a437d 100644
--- a/test/acceptance/authz/helper.go
+++ b/test/acceptance/authz/helper.go
@@ -12,8 +12,13 @@
 package authz
 
 import (
+	"bufio"
+	"context"
+	"strings"
 	"testing"
 
+	"github.com/testcontainers/testcontainers-go"
+
 	"github.com/stretchr/testify/require"
 	gql "github.com/weaviate/weaviate/client/graphql"
 
@@ -163,3 +168,39 @@ func updateTenantStatus(t *testing.T, class string, tenants []*models.Tenant, ke
 	_, err := helper.Client(t).Schema.TenantsUpdate(params, helper.CreateAuth(key))
 	return err
 }
+
+type logScanner struct {
+	container testcontainers.Container
+	pos       int
+}
+
+func newLogScanner(c testcontainers.Container) *logScanner {
+	return &logScanner{container: c}
+}
+
+func (s *logScanner) GetAuthzLogs(t *testing.T) []string {
+	t.Helper() // produces more accurate error tracebacks
+
+	logs, err := s.container.Logs(context.Background())
+	require.Nil(t, err)
+	defer logs.Close()
+
+	scanner := bufio.NewScanner(logs)
+	currentPosition := 0
+
+	var newLines []string
+	for scanner.Scan() {
+		line := scanner.Text()
+		if line == "" {
+			continue
+		}
+		if currentPosition >= s.pos && strings.Contains(line, `"action":"authorize"`) {
+			newLines = append(newLines, line)
+		}
+		currentPosition++
+	}
+
+	s.pos = currentPosition
+
+	return newLines
+}
diff --git a/test/acceptance/authz/nodes_test.go b/test/acceptance/authz/nodes_test.go
index 4a7860edff..988c4dd4a8 100644
--- a/test/acceptance/authz/nodes_test.go
+++ b/test/acceptance/authz/nodes_test.go
@@ -12,11 +12,9 @@
 package authz
 
 import (
-	"errors"
 	"testing"
 
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/client/cluster"
 	"github.com/weaviate/weaviate/client/nodes"
 	"github.com/weaviate/weaviate/entities/models"
@@ -48,16 +46,16 @@ func TestAuthzNodes(t *testing.T) {
 	t.Run("fail to get nodes without minimal read_nodes", func(t *testing.T) {
 		_, err := helper.Client(t).Nodes.NodesGet(nodes.NewNodesGetParams(), helper.CreateAuth(customKey))
 		require.NotNil(t, err)
-		var parsed *nodes.NodesGetForbidden
-		require.True(t, errors.As(err, &parsed))
+		parsed, forbidden := err.(*nodes.NodesGetForbidden)
+		require.True(t, forbidden)
 		require.Contains(t, parsed.Payload.Error[0].Message, "forbidden")
 	})
 
 	t.Run("fail to get cluster stats without read_cluster", func(t *testing.T) {
 		_, err := helper.Client(t).Cluster.ClusterGetStatistics(cluster.NewClusterGetStatisticsParams(), helper.CreateAuth(customKey))
 		require.NotNil(t, err)
-		var parsed *cluster.ClusterGetStatisticsForbidden
-		require.True(t, errors.As(err, &parsed))
+		parsed, forbidden := err.(*cluster.ClusterGetStatisticsForbidden)
+		require.True(t, forbidden)
 		require.Contains(t, parsed.Payload.Error[0].Message, "forbidden")
 	})
 
@@ -90,8 +88,8 @@ func TestAuthzNodes(t *testing.T) {
 	t.Run("fail to get verbose nodes without verbose read_nodes on all collections", func(t *testing.T) {
 		_, err := helper.Client(t).Nodes.NodesGetClass(nodes.NewNodesGetClassParams().WithClassName(clsA.Class).WithOutput(String("verbose")), helper.CreateAuth(customKey))
 		require.NotNil(t, err)
-		var parsed *nodes.NodesGetClassForbidden
-		require.True(t, errors.As(err, &parsed))
+		parsed, forbidden := err.(*nodes.NodesGetClassForbidden)
+		require.True(t, forbidden)
 		require.Contains(t, parsed.Payload.Error[0].Message, "forbidden")
 	})
 
@@ -108,8 +106,8 @@ func TestAuthzNodes(t *testing.T) {
 	t.Run("fail to get verbose nodes on all classes without read_nodes on *", func(t *testing.T) {
 		_, err := helper.Client(t).Nodes.NodesGet(nodes.NewNodesGetParams().WithOutput(String("verbose")), helper.CreateAuth(customKey))
 		require.NotNil(t, err)
-		var parsed *nodes.NodesGetForbidden
-		require.True(t, errors.As(err, &parsed))
+		parsed, forbidden := err.(*nodes.NodesGetForbidden)
+		require.True(t, forbidden)
 		require.Contains(t, parsed.Payload.Error[0].Message, "forbidden")
 	})
 
diff --git a/test/acceptance/authz/rbac_auto_admin_permissions_test.go b/test/acceptance/authz/rbac_auto_admin_permissions_test.go
index e91039236a..c6a4cba45e 100644
--- a/test/acceptance/authz/rbac_auto_admin_permissions_test.go
+++ b/test/acceptance/authz/rbac_auto_admin_permissions_test.go
@@ -12,9 +12,7 @@
 package authz
 
 import (
-	"bufio"
 	"bytes"
-	"context"
 	"fmt"
 	"net/http"
 	"sort"
@@ -22,7 +20,6 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
-	"github.com/testcontainers/testcontainers-go"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/test/helper"
 )
@@ -138,39 +135,3 @@ func (e endpointStatsSlice) String() string {
 	}
 	return str
 }
-
-type logScanner struct {
-	container testcontainers.Container
-	pos       int
-}
-
-func newLogScanner(c testcontainers.Container) *logScanner {
-	return &logScanner{container: c}
-}
-
-func (s *logScanner) GetAuthzLogs(t *testing.T) []string {
-	t.Helper() // produces more accurate error tracebacks
-
-	logs, err := s.container.Logs(context.Background())
-	require.Nil(t, err)
-	defer logs.Close()
-
-	scanner := bufio.NewScanner(logs)
-	currentPosition := 0
-
-	var newLines []string
-	for scanner.Scan() {
-		line := scanner.Text()
-		if line == "" {
-			continue
-		}
-		if currentPosition >= s.pos && strings.Contains(line, `"action":"authorize"`) {
-			newLines = append(newLines, line)
-		}
-		currentPosition++
-	}
-
-	s.pos = currentPosition
-
-	return newLines
-}
diff --git a/test/acceptance/authz/roles_test.go b/test/acceptance/authz/roles_test.go
index 08ed731599..c929aa7d83 100644
--- a/test/acceptance/authz/roles_test.go
+++ b/test/acceptance/authz/roles_test.go
@@ -13,13 +13,11 @@ package authz
 
 import (
 	"context"
-	"errors"
 	"sort"
 	"testing"
 	"time"
 
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/client/authz"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/test/docker"
@@ -147,9 +145,9 @@ func TestAuthzBuiltInRolesJourney(t *testing.T) {
 			clientAuth,
 		)
 		require.NotNil(t, err)
-		var parsed *authz.CreateRoleBadRequest
-		require.True(t, errors.As(err, &parsed))
-		require.Contains(t, parsed.Payload.Error[0].Message, "builtin role")
+		err, failed := err.(*authz.CreateRoleBadRequest)
+		require.True(t, failed)
+		require.Contains(t, err.Payload.Error[0].Message, "builtin role")
 	})
 
 	t.Run("fail to delete builtin role", func(t *testing.T) {
@@ -158,9 +156,9 @@ func TestAuthzBuiltInRolesJourney(t *testing.T) {
 			clientAuth,
 		)
 		require.NotNil(t, err)
-		var parsed *authz.DeleteRoleBadRequest
-		require.True(t, errors.As(err, &parsed))
-		require.Contains(t, parsed.Payload.Error[0].Message, "builtin role")
+		err, failed := err.(*authz.DeleteRoleBadRequest)
+		require.True(t, failed)
+		require.Contains(t, err.Payload.Error[0].Message, "builtin role")
 	})
 
 	t.Run("add builtin role permission", func(t *testing.T) {
@@ -174,9 +172,9 @@ func TestAuthzBuiltInRolesJourney(t *testing.T) {
 			clientAuth,
 		)
 		require.NotNil(t, err)
-		var parsed *authz.AddPermissionsBadRequest
-		require.True(t, errors.As(err, &parsed))
-		require.Contains(t, parsed.Payload.Error[0].Message, "builtin role")
+		err, failed := err.(*authz.AddPermissionsBadRequest)
+		require.True(t, failed)
+		require.Contains(t, err.Payload.Error[0].Message, "builtin role")
 	})
 
 	t.Run("remove builtin role permission", func(t *testing.T) {
@@ -190,9 +188,9 @@ func TestAuthzBuiltInRolesJourney(t *testing.T) {
 			clientAuth,
 		)
 		require.NotNil(t, err)
-		var parsed *authz.RemovePermissionsBadRequest
-		require.True(t, errors.As(err, &parsed))
-		require.Contains(t, parsed.Payload.Error[0].Message, "builtin role")
+		err, failed := err.(*authz.RemovePermissionsBadRequest)
+		require.True(t, failed)
+		require.Contains(t, err.Payload.Error[0].Message, "builtin role")
 	})
 }
 
@@ -233,9 +231,9 @@ func TestAuthzRolesJourney(t *testing.T) {
 	t.Run("fail to create existing role", func(t *testing.T) {
 		_, err = helper.Client(t).Authz.CreateRole(authz.NewCreateRoleParams().WithBody(testRole1), clientAuth)
 		require.NotNil(t, err)
-		var parsed *authz.CreateRoleConflict
-		require.True(t, errors.As(err, &parsed))
-		require.Contains(t, parsed.Payload.Error[0].Message, "already exists")
+		err, conflict := err.(*authz.CreateRoleConflict)
+		require.True(t, conflict)
+		require.Contains(t, err.Payload.Error[0].Message, "already exists")
 	})
 
 	t.Run("get all roles after create", func(t *testing.T) {
@@ -543,8 +541,8 @@ func TestAuthzRolesHasPermission(t *testing.T) {
 			},
 		}), helper.CreateAuth(customKey))
 		require.NotNil(t, err)
-		var parsed *authz.HasPermissionForbidden
-		require.True(t, errors.As(err, &parsed))
+		parsed, forbidden := err.(*authz.HasPermissionForbidden)
+		require.True(t, forbidden)
 		require.Contains(t, parsed.Payload.Error[0].Message, "forbidden")
 	})
 }
diff --git a/test/acceptance/authz/swagger_helper.go b/test/acceptance/authz/swagger_helper.go
index 4c639a7d15..508caaad8e 100644
--- a/test/acceptance/authz/swagger_helper.go
+++ b/test/acceptance/authz/swagger_helper.go
@@ -57,7 +57,7 @@ func newCollector() (*collector, error) {
 func (c *collector) collectEndpoints() ([]endpoint, error) {
 	document, err := loads.Spec("../../../openapi-specs/schema.json")
 	if err != nil {
-		return nil, fmt.Errorf("failed to load Swagger spec: %w", err)
+		return nil, fmt.Errorf("failed to load Swagger spec: %v", err)
 	}
 
 	specDoc := document.Spec()
@@ -82,7 +82,7 @@ func (c *collector) collectEndpoints() ([]endpoint, error) {
 				if param.In == "body" && param.Schema != nil {
 					requestBodyData, err = generateValidRequestBody(&param, specDoc.Definitions)
 					if err != nil {
-						return nil, fmt.Errorf("failed to generate request body data: %w", err)
+						return nil, fmt.Errorf("failed to generate request body data: %v", err)
 					}
 				}
 			}
@@ -194,7 +194,7 @@ func generateValidData(schema *spec.Schema, definitions map[string]spec.Schema)
 				mockData = array
 				jsonData, err := json.Marshal(mockData)
 				if err != nil {
-					return nil, fmt.Errorf("failed to marshal mock data: %w", err)
+					return nil, fmt.Errorf("failed to marshal mock data: %v", err)
 				}
 				return jsonData, nil
 			}
@@ -214,7 +214,7 @@ func generateValidData(schema *spec.Schema, definitions map[string]spec.Schema)
 				mockData = array
 				jsonData, err := json.Marshal(mockData)
 				if err != nil {
-					return nil, fmt.Errorf("failed to marshal mock data: %w", err)
+					return nil, fmt.Errorf("failed to marshal mock data: %v", err)
 				}
 				return jsonData, nil
 			}
@@ -228,7 +228,7 @@ func generateValidData(schema *spec.Schema, definitions map[string]spec.Schema)
 				mockData = array
 				jsonData, err := json.Marshal(mockData)
 				if err != nil {
-					return nil, fmt.Errorf("failed to marshal mock data: %w", err)
+					return nil, fmt.Errorf("failed to marshal mock data: %v", err)
 				}
 				return jsonData, nil
 			}
@@ -272,7 +272,7 @@ func generateValidData(schema *spec.Schema, definitions map[string]spec.Schema)
 
 	jsonData, err := json.Marshal(mockData)
 	if err != nil {
-		return nil, fmt.Errorf("failed to marshal mock data: %w", err)
+		return nil, fmt.Errorf("failed to marshal mock data: %v", err)
 	}
 	return jsonData, nil
 }
diff --git a/test/acceptance/authz/users_test.go b/test/acceptance/authz/users_test.go
index cac8c3b521..9c71c022c0 100644
--- a/test/acceptance/authz/users_test.go
+++ b/test/acceptance/authz/users_test.go
@@ -12,11 +12,9 @@
 package authz
 
 import (
-	"errors"
 	"testing"
 
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/client/authz"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/test/helper"
@@ -51,8 +49,8 @@ func TestAuthzRolesForUsers(t *testing.T) {
 	t.Run("get roles for non existing user", func(t *testing.T) {
 		_, err := helper.Client(t).Authz.GetRolesForUser(authz.NewGetRolesForUserParams().WithID("notExists"), helper.CreateAuth(adminKey))
 		require.NotNil(t, err)
-		var targetErr *authz.GetRolesForUserNotFound
-		require.True(t, errors.As(err, &targetErr))
+		targetErr, ok := err.(*authz.GetRolesForUserNotFound)
+		require.True(t, ok)
 		require.Equal(t, 404, targetErr.Code())
 	})
 }
diff --git a/test/acceptance/batch_request_endpoints/graphql_helper_for_test.go b/test/acceptance/batch_request_endpoints/graphql_helper_for_test.go
index 8b59a7a724..c01926ad38 100644
--- a/test/acceptance/batch_request_endpoints/graphql_helper_for_test.go
+++ b/test/acceptance/batch_request_endpoints/graphql_helper_for_test.go
@@ -13,12 +13,10 @@ package batch_request_endpoints
 
 import (
 	"encoding/json"
-	"errors"
 	"fmt"
 	"testing"
 
 	"github.com/go-openapi/runtime"
-
 	"github.com/weaviate/weaviate/client/graphql"
 	graphql_client "github.com/weaviate/weaviate/client/graphql"
 	"github.com/weaviate/weaviate/entities/models"
@@ -45,8 +43,8 @@ func QueryGraphQL(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, operation
 func AssertGraphQL(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, query string) *GraphQLResult {
 	response, err := QueryGraphQL(t, auth, "", query, nil)
 	if err != nil {
-		var parsedErr *graphql.GraphqlPostUnprocessableEntity
-		if !errors.As(err, &parsedErr) {
+		parsedErr, ok := err.(*graphql.GraphqlPostUnprocessableEntity)
+		if !ok {
 			t.Fatalf("Expected the query to succeed, but failed due to: %+v", err)
 		}
 		t.Fatalf("Expected the query to succeed, but failed with unprocessable entity: %v", parsedErr.Payload.Error[0])
diff --git a/test/acceptance/classifications/graphql_helper.go b/test/acceptance/classifications/graphql_helper.go
index ef23c6ede4..33a5dfdf27 100644
--- a/test/acceptance/classifications/graphql_helper.go
+++ b/test/acceptance/classifications/graphql_helper.go
@@ -13,12 +13,10 @@ package test
 
 import (
 	"encoding/json"
-	"errors"
 	"fmt"
 	"testing"
 
 	"github.com/go-openapi/runtime"
-
 	"github.com/weaviate/weaviate/client/graphql"
 	graphql_client "github.com/weaviate/weaviate/client/graphql"
 	"github.com/weaviate/weaviate/entities/models"
@@ -45,11 +43,11 @@ func QueryGraphQL(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, operation
 func AssertGraphQL(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, query string) *GraphQLResult {
 	response, err := QueryGraphQL(t, auth, "", query, nil)
 	if err != nil {
-		var parsedErr *graphql.GraphqlPostUnprocessableEntity
-		if !errors.As(err, &parsedErr) {
+		parsedErr, ok := err.(*graphql.GraphqlPostUnprocessableEntity)
+		if !ok {
 			t.Fatalf("Expected the query to succeed, but failed due to: %#v", err)
 		}
-		t.Fatalf("Expected the query to succeed, but failed with unprocessable entity: %#v", parsedErr.Payload.Error[0])
+		t.Fatalf("Expected the query to succeed, but failed with unprocessable entity: %v", parsedErr.Payload.Error[0])
 	}
 
 	if len(response.Errors) != 0 {
diff --git a/test/acceptance/multi_node/nodes_api_test.go b/test/acceptance/multi_node/nodes_api_test.go
deleted file mode 100644
index 4e69161079..0000000000
--- a/test/acceptance/multi_node/nodes_api_test.go
+++ /dev/null
@@ -1,98 +0,0 @@
-//                           _       _
-// __      _____  __ ___   ___  __ _| |_ ___
-// \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
-//  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
-//   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
-//
-//  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
-//
-//  CONTACT: hello@weaviate.io
-//
-
-package multi_node
-
-import (
-	"context"
-	"testing"
-
-	"github.com/stretchr/testify/require"
-	"github.com/weaviate/weaviate/client/nodes"
-	"github.com/weaviate/weaviate/entities/models"
-	"github.com/weaviate/weaviate/entities/verbosity"
-	"github.com/weaviate/weaviate/test/docker"
-	"github.com/weaviate/weaviate/test/helper"
-	"github.com/weaviate/weaviate/test/helper/sample-schema/articles"
-)
-
-func TestNodesMultiNode(t *testing.T) {
-	ctx := context.Background()
-
-	compose, err := docker.New().
-		With3NodeCluster().
-		Start(ctx)
-	require.NoError(t, err)
-	defer func() {
-		if err := compose.Terminate(ctx); err != nil {
-			t.Fatalf("failed to terminate test containers: %s", err.Error())
-		}
-	}()
-	helper.SetupClient(compose.GetWeaviate().URI())
-
-	paragraphClass := articles.ParagraphsClass()
-	helper.DeleteClass(t, paragraphClass.Class)
-	helper.CreateClass(t, paragraphClass)
-	articleClass := articles.ArticlesClass()
-	helper.DeleteClass(t, articleClass.Class)
-	helper.CreateClass(t, articleClass)
-
-	for i := 0; i < 10; i++ {
-		require.NoError(t, helper.CreateObject(t, articles.NewArticle().Object()))
-		require.NoError(t, helper.CreateObject(t, articles.NewParagraph().Object()))
-	}
-
-	minimal, verbose := verbosity.OutputMinimal, verbosity.OutputVerbose
-
-	t.Run("output without class minimal", func(t *testing.T) {
-		payload := getNodesPayload(t, minimal, "")
-		for _, node := range payload.Nodes {
-			require.Nil(t, node.Shards)
-		}
-	})
-
-	t.Run("output without class verbose", func(t *testing.T) {
-		payload := getNodesPayload(t, verbose, "")
-		for _, node := range payload.Nodes {
-			require.NotNil(t, node.Shards)
-			require.Len(t, node.Shards, 2)
-		}
-	})
-
-	t.Run("output with class minimal", func(t *testing.T) {
-		payload := getNodesPayload(t, minimal, articleClass.Class)
-		for _, node := range payload.Nodes {
-			require.Nil(t, node.Shards)
-		}
-	})
-
-	t.Run("output with class verbose", func(t *testing.T) {
-		payload := getNodesPayload(t, verbose, articleClass.Class)
-		for _, node := range payload.Nodes {
-			require.NotNil(t, node.Shards)
-			require.Len(t, node.Shards, 1)
-		}
-	})
-}
-
-func getNodesPayload(t *testing.T, verbosity string, class string) *models.NodesStatusResponse {
-	params := nodes.NewNodesGetClassParams().WithOutput(&verbosity)
-	if class != "" {
-		params.WithClassName(class)
-	}
-	body, clientErr := helper.Client(t).Nodes.NodesGetClass(params, nil)
-	require.NoError(t, clientErr)
-	payload, err := body.Payload, clientErr
-	require.NoError(t, err)
-	require.NotNil(t, payload)
-	require.Len(t, payload.Nodes, 3)
-	return payload
-}
diff --git a/test/acceptance/multi_tenancy/get_tenant_objects_test.go b/test/acceptance/multi_tenancy/get_tenant_objects_test.go
index e3ddf2f221..1fa486de79 100644
--- a/test/acceptance/multi_tenancy/get_tenant_objects_test.go
+++ b/test/acceptance/multi_tenancy/get_tenant_objects_test.go
@@ -16,7 +16,6 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/client/objects"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/entities/schema"
@@ -369,7 +368,7 @@ func TestListTenantObjects(t *testing.T) {
 			require.NotNil(t, err)
 			expErr := &objects.ObjectsListUnprocessableEntity{}
 			require.ErrorAs(t, err, &expErr)
-			assert.Contains(t, expErr.Payload.Error[0].Message, tenantNames[0])
+			assert.Contains(t, err.(*objects.ObjectsListUnprocessableEntity).Payload.Error[0].Message, tenantNames[0])
 			require.Nil(t, res)
 		})
 	})
@@ -418,7 +417,7 @@ func TestListTenantObjects(t *testing.T) {
 			require.NotNil(t, err)
 			expErr := &objects.ObjectsListUnprocessableEntity{}
 			require.ErrorAs(t, err, &expErr)
-			assert.Contains(t, expErr.Payload.Error[0].Message, tenantNames[1])
+			assert.Contains(t, err.(*objects.ObjectsListUnprocessableEntity).Payload.Error[0].Message, tenantNames[1])
 			require.Nil(t, res)
 		})
 
diff --git a/test/acceptance/multi_tenancy/patch_tenant_objects_test.go b/test/acceptance/multi_tenancy/patch_tenant_objects_test.go
index f983959b05..0403f4c569 100644
--- a/test/acceptance/multi_tenancy/patch_tenant_objects_test.go
+++ b/test/acceptance/multi_tenancy/patch_tenant_objects_test.go
@@ -12,14 +12,12 @@
 package test
 
 import (
-	"errors"
 	"fmt"
 	"net/http"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/client/objects"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/entities/schema"
@@ -190,8 +188,8 @@ func TestPatchTenantObjects_ChangeTenant(t *testing.T) {
 			WithID(toUpdate.ID).WithBody(&toUpdate)
 		_, err := helper.Client(t).Objects.ObjectsClassPatch(params, nil)
 		require.NotNil(t, err) // tenant does not exist
-		var parsedErr *objects.ObjectsClassPatchUnprocessableEntity
-		require.True(t, errors.As(err, &parsedErr))
+		parsedErr, ok := err.(*objects.ObjectsClassPatchUnprocessableEntity)
+		require.True(t, ok)
 		require.NotNil(t, parsedErr.Payload.Error)
 		require.Len(t, parsedErr.Payload.Error, 1)
 		assert.Contains(t, err.Error(), fmt.Sprint(http.StatusUnprocessableEntity))
diff --git a/test/acceptance/multi_tenancy/update_tenant_objects_test.go b/test/acceptance/multi_tenancy/update_tenant_objects_test.go
index 8d0345e9e0..92894ede1d 100644
--- a/test/acceptance/multi_tenancy/update_tenant_objects_test.go
+++ b/test/acceptance/multi_tenancy/update_tenant_objects_test.go
@@ -12,14 +12,12 @@
 package test
 
 import (
-	"errors"
 	"fmt"
 	"net/http"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/client/objects"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/entities/schema"
@@ -190,8 +188,8 @@ func TestUpdateTenantObjects_UpdateTenant(t *testing.T) {
 			WithID(toUpdate.ID).WithBody(&toUpdate)
 		_, err := helper.Client(t).Objects.ObjectsClassPut(params, nil)
 		require.NotNil(t, err) // tenant does not exist
-		var parsedErr *objects.ObjectsClassPutUnprocessableEntity
-		require.True(t, errors.As(err, &parsedErr))
+		parsedErr, ok := err.(*objects.ObjectsClassPutUnprocessableEntity)
+		require.True(t, ok)
 		require.NotNil(t, parsedErr.Payload.Error)
 		require.Len(t, parsedErr.Payload.Error, 1)
 		assert.Contains(t, err.Error(), fmt.Sprint(http.StatusUnprocessableEntity))
diff --git a/test/acceptance/objects/custom_vectors.go b/test/acceptance/objects/custom_vectors.go
index 5dccee0b0b..7c675dc596 100644
--- a/test/acceptance/objects/custom_vectors.go
+++ b/test/acceptance/objects/custom_vectors.go
@@ -14,10 +14,10 @@ package test
 import (
 	"testing"
 
+	"github.com/davecgh/go-spew/spew"
 	"github.com/go-openapi/strfmt"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/client/objects"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/test/helper"
@@ -73,6 +73,9 @@ func customVectors(t *testing.T) {
 			Vector:     []float32{0.4, 0.3},
 		})
 		_, err := helper.Client(t).Objects.ObjectsPatch(params, nil)
+		if err != nil {
+			spew.Dump(err.(*objects.ObjectsPatchInternalServerError).Payload.Error[0])
+		}
 		require.Nil(t, err, "patch should succeed")
 	})
 
diff --git a/test/acceptance/objects/objects_test.go b/test/acceptance/objects/objects_test.go
index cadbbd3382..acaeb48dab 100644
--- a/test/acceptance/objects/objects_test.go
+++ b/test/acceptance/objects/objects_test.go
@@ -20,6 +20,7 @@ import (
 	"testing"
 
 	"github.com/go-openapi/strfmt"
+
 	"github.com/stretchr/testify/assert"
 
 	"github.com/weaviate/weaviate/client/objects"
@@ -116,8 +117,8 @@ func creatingObjects(t *testing.T) {
 
 		resp, err = helper.Client(t).Objects.ObjectsCreate(params, nil)
 		helper.AssertRequestFail(t, resp, err, func() {
-			var errResponse *objects.ObjectsCreateUnprocessableEntity
-			if !errors.As(err, &errResponse) {
+			errResponse, ok := err.(*objects.ObjectsCreateUnprocessableEntity)
+			if !ok {
 				t.Fatalf("Did not get not found response, but %#v", err)
 			}
 
@@ -312,8 +313,8 @@ func creatingObjects(t *testing.T) {
 				params := objects.NewObjectsCreateParams().WithBody(example.object())
 				resp, err := helper.Client(t).Objects.ObjectsCreate(params, nil)
 				helper.AssertRequestFail(t, resp, err, func() {
-					var errResponse *objects.ObjectsCreateUnprocessableEntity
-					if !errors.As(err, &errResponse) {
+					errResponse, ok := err.(*objects.ObjectsCreateUnprocessableEntity)
+					if !ok {
 						t.Fatalf("Did not get not found response, but %#v", err)
 					}
 					example.errorCheck(t, errResponse.Payload)
diff --git a/test/acceptance/replication/read_repair/crud_test.go b/test/acceptance/replication/read_repair/crud_test.go
index 7c30d5fafb..85977c4c53 100644
--- a/test/acceptance/replication/read_repair/crud_test.go
+++ b/test/acceptance/replication/read_repair/crud_test.go
@@ -14,7 +14,6 @@ package replication
 import (
 	"context"
 	"encoding/json"
-	"errors"
 	"fmt"
 	"testing"
 	"time"
@@ -23,7 +22,6 @@ import (
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"github.com/stretchr/testify/suite"
-
 	"github.com/weaviate/weaviate/client/objects"
 	"github.com/weaviate/weaviate/client/schema"
 	"github.com/weaviate/weaviate/entities/models"
@@ -483,8 +481,8 @@ func (suite *ReplicationTestSuite) TestEventualReplicaCRUD() {
 			resp, err := helper.Client(t).Schema.SchemaObjectsUpdate(params, nil)
 			require.NotNil(t, err)
 			helper.AssertRequestFail(t, resp, err, func() {
-				var errResponse *schema.SchemaObjectsUpdateUnprocessableEntity
-				require.True(t, errors.As(err, &errResponse))
+				errResponse, ok := err.(*schema.SchemaObjectsUpdateUnprocessableEntity)
+				require.True(t, ok)
 				require.Equal(t, fmt.Sprintf("scale \"%s\" from 3 replicas to 2: scaling in not supported yet", ac.Class), errResponse.Payload.Error[0].Message)
 			})
 		})
diff --git a/test/acceptance/schema/add_class_test.go b/test/acceptance/schema/add_class_test.go
index 1fe5a1f093..57220c6a04 100644
--- a/test/acceptance/schema/add_class_test.go
+++ b/test/acceptance/schema/add_class_test.go
@@ -12,7 +12,6 @@
 package test
 
 import (
-	"errors"
 	"fmt"
 	"testing"
 
@@ -49,8 +48,8 @@ func TestInvalidDataTypeInProperty(t *testing.T) {
 		params := clschema.NewSchemaObjectsCreateParams().WithObjectClass(c)
 		resp, err := helper.Client(t).Schema.SchemaObjectsCreate(params, nil)
 		helper.AssertRequestFail(t, resp, err, func() {
-			var parsed *clschema.SchemaObjectsCreateUnprocessableEntity
-			require.True(t, errors.As(err, &parsed), "error should be unprocessable entity")
+			parsed, ok := err.(*clschema.SchemaObjectsCreateUnprocessableEntity)
+			require.True(t, ok, "error should be unprocessable entity")
 			assert.Equal(t, "property 'someProperty': invalid dataType: []: dataType cannot be an empty string",
 				parsed.Payload.Error[0].Message)
 		})
@@ -80,8 +79,8 @@ func TestInvalidPropertyName(t *testing.T) {
 		params := clschema.NewSchemaObjectsCreateParams().WithObjectClass(c)
 		resp, err := helper.Client(t).Schema.SchemaObjectsCreate(params, nil)
 		helper.AssertRequestFail(t, resp, err, func() {
-			var parsed *clschema.SchemaObjectsCreateUnprocessableEntity
-			require.True(t, errors.As(err, &parsed), "error should be unprocessable entity")
+			parsed, ok := err.(*clschema.SchemaObjectsCreateUnprocessableEntity)
+			require.True(t, ok, "error should be unprocessable entity")
 			assert.Equal(t, "'some-property' is not a valid property name. Property names in Weaviate "+
 				"are restricted to valid GraphQL names, which must be “/[_A-Za-z][_0-9A-Za-z]{0,230}/”.",
 				parsed.Payload.Error[0].Message)
@@ -147,8 +146,7 @@ func TestUpdateHNSWSettingsAfterAddingRefProps(t *testing.T) {
 		_, err := helper.Client(t).Schema.SchemaObjectsDelete(params, nil)
 		assert.Nil(t, err)
 		if err != nil {
-			var typed *clschema.SchemaObjectsDeleteBadRequest
-			if errors.As(err, &typed) {
+			if typed, ok := err.(*clschema.SchemaObjectsDeleteBadRequest); ok {
 				fmt.Println(typed.Payload.Error[0].Message)
 			}
 		}
@@ -251,8 +249,7 @@ func TestUpdateClassWithoutVectorIndex(t *testing.T) {
 		_, err := helper.Client(t).Schema.SchemaObjectsDelete(params, nil)
 		assert.Nil(t, err)
 		if err != nil {
-			var typed *clschema.SchemaObjectsDeleteBadRequest
-			if errors.As(err, &typed) {
+			if typed, ok := err.(*clschema.SchemaObjectsDeleteBadRequest); ok {
 				fmt.Println(typed.Payload.Error[0].Message)
 			}
 		}
@@ -316,8 +313,7 @@ func TestUpdateDistanceSettings(t *testing.T) {
 		_, err := helper.Client(t).Schema.SchemaObjectsDelete(params, nil)
 		assert.Nil(t, err)
 		if err != nil {
-			var typed *clschema.SchemaObjectsDeleteBadRequest
-			if errors.As(err, &typed) {
+			if typed, ok := err.(*clschema.SchemaObjectsDeleteBadRequest); ok {
 				fmt.Println(typed.Payload.Error[0].Message)
 			}
 		}
diff --git a/test/acceptance/vector_distances/graphql_helper_test.go b/test/acceptance/vector_distances/graphql_helper_test.go
index f5687c280c..18305085f4 100644
--- a/test/acceptance/vector_distances/graphql_helper_test.go
+++ b/test/acceptance/vector_distances/graphql_helper_test.go
@@ -13,12 +13,10 @@ package test
 
 import (
 	"encoding/json"
-	"errors"
 	"fmt"
 	"testing"
 
 	"github.com/go-openapi/runtime"
-
 	"github.com/weaviate/weaviate/client/graphql"
 	graphql_client "github.com/weaviate/weaviate/client/graphql"
 	"github.com/weaviate/weaviate/entities/models"
@@ -45,8 +43,8 @@ func QueryGraphQL(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, operation
 func QueryGraphQLOrFatal(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, operation string, query string, variables map[string]interface{}) *models.GraphQLResponse {
 	response, err := QueryGraphQL(t, auth, operation, query, variables)
 	if err != nil {
-		var parsedErr *graphql.GraphqlPostUnprocessableEntity
-		if !errors.As(err, &parsedErr) {
+		parsedErr, ok := err.(*graphql.GraphqlPostUnprocessableEntity)
+		if !ok {
 			t.Fatalf("Expected the query to succeed, but failed due to: %#v", err)
 		}
 		t.Fatalf("Expected the query to succeed, but failed with unprocessable entity: %v", parsedErr.Payload.Error[0])
diff --git a/test/benchmark/benchmark_sift.go b/test/benchmark/benchmark_sift.go
index 983b8fd0a4..50c84f2d19 100644
--- a/test/benchmark/benchmark_sift.go
+++ b/test/benchmark/benchmark_sift.go
@@ -21,12 +21,12 @@ import (
 	"os"
 	"sync"
 
+	"github.com/sirupsen/logrus"
+	enterrors "github.com/weaviate/weaviate/entities/errors"
+
 	"github.com/go-openapi/strfmt"
 	"github.com/google/uuid"
 	"github.com/pkg/errors"
-	"github.com/sirupsen/logrus"
-
-	enterrors "github.com/weaviate/weaviate/entities/errors"
 	"github.com/weaviate/weaviate/entities/models"
 )
 
@@ -99,7 +99,7 @@ func readSiftFloat(file string, maxObjects int) []*models.Object {
 	vectorBytes := make([]byte, bytesPerF+vectorLengthFloat*bytesPerF)
 	for i := 0; i >= 0; i++ {
 		_, err = f.Read(vectorBytes)
-		if errors.Is(err, io.EOF) {
+		if err == io.EOF {
 			break
 		} else if err != nil {
 			panic(err)
diff --git a/test/docker/ollama.go b/test/docker/ollama.go
index 64af59d855..a565e86c86 100644
--- a/test/docker/ollama.go
+++ b/test/docker/ollama.go
@@ -59,11 +59,11 @@ func startOllama(ctx context.Context, networkName, hostname, model string) (*Doc
 		// pull a given model
 		_, _, err = container.Exec(ctx, []string{"ollama", "pull", model})
 		if err != nil {
-			return nil, fmt.Errorf("failed to pull model %s: %w", model, err)
+			return nil, fmt.Errorf("failed to pull model %s: %s", model, err)
 		}
 		_, _, err = container.Exec(ctx, []string{"ollama", "run", model})
 		if err != nil {
-			return nil, fmt.Errorf("failed to run model %s: %w", model, err)
+			return nil, fmt.Errorf("failed to run model %s: %s", model, err)
 		}
 	}
 	uri, err := container.PortEndpoint(ctx, port, "")
diff --git a/test/helper/graphql/graphql_helper.go b/test/helper/graphql/graphql_helper.go
index b17f0fee88..68d57c5027 100644
--- a/test/helper/graphql/graphql_helper.go
+++ b/test/helper/graphql/graphql_helper.go
@@ -13,7 +13,6 @@ package graphqlhelper
 
 import (
 	"encoding/json"
-	"errors"
 	"fmt"
 	"strings"
 	"testing"
@@ -21,7 +20,6 @@ import (
 
 	"github.com/go-openapi/runtime"
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/client/graphql"
 	graphql_client "github.com/weaviate/weaviate/client/graphql"
 	"github.com/weaviate/weaviate/entities/models"
@@ -73,8 +71,8 @@ func QueryGraphQLOrFatalWithTimeout(t *testing.T, auth runtime.ClientAuthInfoWri
 func getGraphQLResponseOrFatal(t *testing.T, response *models.GraphQLResponse, err error) *models.GraphQLResponse {
 	t.Helper()
 	if err != nil {
-		var parsedErr *graphql.GraphqlPostUnprocessableEntity
-		if !errors.As(err, &parsedErr) {
+		parsedErr, ok := err.(*graphql.GraphqlPostUnprocessableEntity)
+		if !ok {
 			t.Fatalf("Expected the query to succeed, but failed due to: %#v", err)
 		}
 		t.Fatalf("Expected the query to succeed, but failed with unprocessable entity: %v", parsedErr.Payload.Error[0])
diff --git a/test/helper/journey/backup_and_restore_journey.go b/test/helper/journey/backup_and_restore_journey.go
index 711b8ebc05..4a8fa6abf1 100644
--- a/test/helper/journey/backup_and_restore_journey.go
+++ b/test/helper/journey/backup_and_restore_journey.go
@@ -12,13 +12,11 @@
 package journey
 
 import (
-	"errors"
 	"strconv"
 	"testing"
 	"time"
 
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/client/backups"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/test/helper"
@@ -82,8 +80,8 @@ func backupAndRestoreJourneyTest(t *testing.T, weaviateEndpoint, backend string,
 		}, booksClass.Class, backend, backupID)
 
 		helper.AssertRequestFail(t, resp, err, func() {
-			var customErr *backups.BackupsCreateUnprocessableEntity
-			require.True(t, errors.As(err, &customErr), "not backups.BackupsCreateUnprocessableEntity")
+			_, ok := err.(*backups.BackupsCreateUnprocessableEntity)
+			require.True(t, ok, "not backups.BackupsCreateUnprocessableEntity")
 		})
 
 		// out of band cpu %
@@ -91,8 +89,8 @@ func backupAndRestoreJourneyTest(t *testing.T, weaviateEndpoint, backend string,
 			CPUPercentage: 120,
 		}, booksClass.Class, backend, backupID)
 		helper.AssertRequestFail(t, resp, err, func() {
-			var customErr *backups.BackupsCreateUnprocessableEntity
-			require.True(t, errors.As(err, &customErr), "not backups.BackupsCreateUnprocessableEntity")
+			_, ok := err.(*backups.BackupsCreateUnprocessableEntity)
+			require.True(t, ok, "not backups.BackupsCreateUnprocessableEntity")
 		})
 
 		// out of band chunkSize
@@ -100,8 +98,8 @@ func backupAndRestoreJourneyTest(t *testing.T, weaviateEndpoint, backend string,
 			ChunkSize: 1024,
 		}, booksClass.Class, backend, backupID)
 		helper.AssertRequestFail(t, resp, err, func() {
-			var customErr *backups.BackupsCreateUnprocessableEntity
-			require.True(t, errors.As(err, &customErr), "not backups.BackupsCreateUnprocessableEntity")
+			_, ok := err.(*backups.BackupsCreateUnprocessableEntity)
+			require.True(t, ok, "not backups.BackupsCreateUnprocessableEntity")
 		})
 	})
 
@@ -187,8 +185,8 @@ func backupAndRestoreJourneyTest(t *testing.T, weaviateEndpoint, backend string,
 		}, booksClass.Class, backend, backupID, map[string]string{})
 
 		helper.AssertRequestFail(t, resp, err, func() {
-			var customErr *backups.BackupsRestoreUnprocessableEntity
-			require.True(t, errors.As(err, &customErr), "not backups.BackupsRestoreUnprocessableEntity")
+			_, ok := err.(*backups.BackupsRestoreUnprocessableEntity)
+			require.True(t, ok, "not backups.BackupsRestoreUnprocessableEntity")
 		})
 	})
 
diff --git a/test/helper/modules/modules_helper.go b/test/helper/modules/modules_helper.go
index 044e1d660f..6d5d10e712 100644
--- a/test/helper/modules/modules_helper.go
+++ b/test/helper/modules/modules_helper.go
@@ -14,7 +14,6 @@ package moduleshelper
 import (
 	"context"
 	"encoding/json"
-	"errors"
 	"fmt"
 	"os"
 	"path/filepath"
@@ -25,11 +24,10 @@ import (
 	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-	"google.golang.org/api/iterator"
-	"google.golang.org/api/option"
-
 	"github.com/weaviate/weaviate/test/helper"
 	graphqlhelper "github.com/weaviate/weaviate/test/helper/graphql"
+	"google.golang.org/api/iterator"
+	"google.golang.org/api/option"
 )
 
 func EnsureClassExists(t *testing.T, className string, tenant string) {
@@ -121,7 +119,7 @@ func DeleteGCSBucket(ctx context.Context, t *testing.T, bucketName string) {
 		it := bucket.Objects(ctx, nil)
 		for {
 			objAttrs, err := it.Next()
-			if errors.Is(err, iterator.Done) {
+			if err == iterator.Done {
 				break
 			}
 			assert.Nil(t, err)
diff --git a/usecases/auth/authentication/oidc/middleware_test.go b/usecases/auth/authentication/oidc/middleware_test.go
index 6f32eb5d01..c68f2576a4 100644
--- a/usecases/auth/authentication/oidc/middleware_test.go
+++ b/usecases/auth/authentication/oidc/middleware_test.go
@@ -20,7 +20,6 @@ import (
 	"github.com/golang-jwt/jwt/v4"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/usecases/config"
 )
 
@@ -54,7 +53,7 @@ func Test_Middleware_IncompleteConfiguration(t *testing.T) {
 		"missing required field 'username_claim', missing required field 'client_id': either set a client_id or explicitly disable the check with 'skip_client_id_check: true'")
 
 	_, err := New(cfg)
-	assert.ErrorAs(t, err, &expectedErr)
+	assert.Equal(t, expectedErr, err)
 }
 
 type claims struct {
diff --git a/usecases/backup/restorer_test.go b/usecases/backup/restorer_test.go
index 263c75eb69..d0dbd49a9d 100644
--- a/usecases/backup/restorer_test.go
+++ b/usecases/backup/restorer_test.go
@@ -23,7 +23,6 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
-
 	"github.com/weaviate/weaviate/entities/backup"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/usecases/sharding"
@@ -174,7 +173,7 @@ func TestRestoreRequestValidation(t *testing.T) {
 		m3 := createManager(nil, nil, backend, nil)
 
 		_, err = m3.Restore(ctx, nil, req)
-		if !errors.As(err, &backup.ErrNotFound{}) {
+		if _, ok := err.(backup.ErrNotFound); !ok {
 			t.Errorf("must return an error if meta data doesn't exist: %v", err)
 		}
 	})
diff --git a/usecases/backup/scheduler_test.go b/usecases/backup/scheduler_test.go
index 8d7ab900d3..1c05416c9f 100644
--- a/usecases/backup/scheduler_test.go
+++ b/usecases/backup/scheduler_test.go
@@ -24,7 +24,6 @@ import (
 	"github.com/sirupsen/logrus/hooks/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
-
 	"github.com/weaviate/weaviate/entities/backup"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/usecases/auth/authorization"
@@ -667,7 +666,7 @@ func TestSchedulerRestoreRequestValidation(t *testing.T) {
 		fs.backend.On("GetObject", ctx, id, BackupFile).Return(nil, backup.ErrNotFound{})
 
 		_, err = fs.scheduler().Restore(ctx, nil, req)
-		if !errors.As(err, &backup.ErrNotFound{}) {
+		if _, ok := err.(backup.ErrNotFound); !ok {
 			t.Errorf("must return an error if meta data doesn't exist: %v", err)
 		}
 	})
diff --git a/usecases/classification/fakes_for_test.go b/usecases/classification/fakes_for_test.go
index 625708c908..99ddced762 100644
--- a/usecases/classification/fakes_for_test.go
+++ b/usecases/classification/fakes_for_test.go
@@ -404,7 +404,7 @@ func (c *fakeModuleClassifyFn) classifyFn(item search.Result, itemIndex int,
 
 	err := writer.Store(item)
 	if err != nil {
-		return fmt.Errorf("store %s/%s: %w", item.ClassName, item.ID, err)
+		return fmt.Errorf("store %s/%s: %v", item.ClassName, item.ID, err)
 	}
 	return nil
 }
diff --git a/usecases/classification/validation_test.go b/usecases/classification/validation_test.go
index aa29abd927..d194ed3273 100644
--- a/usecases/classification/validation_test.go
+++ b/usecases/classification/validation_test.go
@@ -16,7 +16,6 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
-
 	"github.com/weaviate/weaviate/entities/models"
 )
 
@@ -181,7 +180,7 @@ func Test_ValidateUserInput(t *testing.T) {
 			fsg := &fakeSchemaGetter{testSchema()}
 			validator := NewValidator(fsg.ReadOnlyClass, test.input)
 			err := validator.Do()
-			assert.ErrorAs(t, err, &test.expectedError)
+			assert.Equal(t, test.expectedError, err)
 		})
 	}
 }
diff --git a/usecases/objects/authorization_test.go b/usecases/objects/authorization_test.go
index d3f7a25bd0..a10a051e6f 100644
--- a/usecases/objects/authorization_test.go
+++ b/usecases/objects/authorization_test.go
@@ -18,12 +18,12 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/go-openapi/strfmt"
 	"github.com/google/uuid"
+
+	"github.com/go-openapi/strfmt"
 	"github.com/sirupsen/logrus/hooks/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/usecases/auth/authorization"
@@ -190,8 +190,7 @@ func Test_Kinds_Authorization(t *testing.T) {
 
 				require.Len(t, authorizer.Calls(), 1, "authorizer must be called")
 				aerr := out[len(out)-1].Interface().(error)
-				var customErr *Error
-				if !errors.As(aerr, &customErr) || !customErr.Forbidden() {
+				if err, ok := aerr.(*Error); !ok || !err.Forbidden() {
 					assert.Equal(t, errors.New("just a test fake"), aerr,
 						"execution must abort with authorizer error")
 				}
diff --git a/usecases/objects/delete_test.go b/usecases/objects/delete_test.go
index ef2815c387..bda4dc4c1d 100644
--- a/usecases/objects/delete_test.go
+++ b/usecases/objects/delete_test.go
@@ -20,7 +20,6 @@ import (
 	"github.com/sirupsen/logrus/hooks/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
-
 	"github.com/weaviate/weaviate/entities/search"
 	"github.com/weaviate/weaviate/usecases/auth/authorization/mocks"
 	"github.com/weaviate/weaviate/usecases/config"
@@ -61,7 +60,7 @@ func Test_DeleteObject(t *testing.T) {
 	// return internal error if deleteObject() fails
 	repo.On("DeleteObject", cls, id, mock.Anything).Return(errNotFound).Once()
 	err = manager.DeleteObject(context.Background(), nil, cls, id, nil, "")
-	if !errors.As(err, &ErrInternal{}) {
+	if _, ok := err.(ErrInternal); !ok {
 		t.Errorf("error type got: %T want: ErrInternal", err)
 	}
 	repo.AssertExpectations(t)
diff --git a/usecases/objects/fakes_for_test.go b/usecases/objects/fakes_for_test.go
index 13be9d8402..1e39202e5e 100644
--- a/usecases/objects/fakes_for_test.go
+++ b/usecases/objects/fakes_for_test.go
@@ -18,16 +18,16 @@ import (
 	"strings"
 	"time"
 
+	"github.com/weaviate/weaviate/entities/dto"
+
 	"github.com/go-openapi/strfmt"
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
 	"github.com/stretchr/testify/mock"
 	"github.com/tailor-inc/graphql"
 	"github.com/tailor-inc/graphql/language/ast"
-
 	"github.com/weaviate/weaviate/adapters/handlers/graphql/descriptions"
 	"github.com/weaviate/weaviate/entities/additional"
-	"github.com/weaviate/weaviate/entities/dto"
 	"github.com/weaviate/weaviate/entities/filters"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/entities/modulecapabilities"
@@ -238,9 +238,8 @@ func (f *fakeVectorRepo) ObjectSearch(ctx context.Context, offset, limit int, fi
 
 func (f *fakeVectorRepo) Query(ctx context.Context, q *QueryInput) (search.Results, *Error) {
 	args := f.Called(q)
-	var customEr *Error
-	errors.As(args.Error(1), &customEr)
-	return args.Get(0).([]search.Result), customEr
+	res, err := args.Get(0).([]search.Result), args.Error(1).(*Error)
+	return res, err
 }
 
 func (f *fakeVectorRepo) PutObject(ctx context.Context, concept *models.Object, vector []float32,
diff --git a/usecases/objects/get_test.go b/usecases/objects/get_test.go
index 5b0518427d..b9ed2c7a5a 100644
--- a/usecases/objects/get_test.go
+++ b/usecases/objects/get_test.go
@@ -21,7 +21,6 @@ import (
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/entities/additional"
 	"github.com/weaviate/weaviate/entities/filters"
 	"github.com/weaviate/weaviate/entities/models"
@@ -294,7 +293,7 @@ func Test_GetAction(t *testing.T) {
 							"featureProjection": getDefaultParam("featureProjection"),
 						},
 					}, nil, "")
-				assert.Equal(t, errors.New("get extend: unknown capability: featureProjection").Error(), err.Error())
+				assert.Equal(t, errors.New("get extend: unknown capability: featureProjection"), err)
 			})
 
 			t.Run("semantic path", func(t *testing.T) {
@@ -313,7 +312,7 @@ func Test_GetAction(t *testing.T) {
 							"semanticPath": getDefaultParam("semanticPath"),
 						},
 					}, nil, "")
-				assert.Equal(t, errors.New("get extend: unknown capability: semanticPath").Error(), err.Error())
+				assert.Equal(t, errors.New("get extend: unknown capability: semanticPath"), err)
 			})
 
 			t.Run("nearest neighbors", func(t *testing.T) {
@@ -779,7 +778,7 @@ func Test_GetThing(t *testing.T) {
 							"featureProjection": getDefaultParam("featureProjection"),
 						},
 					}, nil, "")
-				assert.Equal(t, errors.New("get extend: unknown capability: featureProjection").Error(), err.Error())
+				assert.Equal(t, errors.New("get extend: unknown capability: featureProjection"), err)
 			})
 
 			t.Run("nearest neighbors", func(t *testing.T) {
diff --git a/usecases/objects/validation/phone_numbers_test.go b/usecases/objects/validation/phone_numbers_test.go
index 4c31440967..5f975c4e36 100644
--- a/usecases/objects/validation/phone_numbers_test.go
+++ b/usecases/objects/validation/phone_numbers_test.go
@@ -19,7 +19,6 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/usecases/config"
 )
@@ -170,13 +169,7 @@ func TestPropertyOfTypePhoneNumberValidation(t *testing.T) {
 			}
 			schema := testSchema()
 			err := validator.properties(context.Background(), schema.Objects.Classes[0], obj, nil)
-
-			if test.expectedErr != nil {
-				assert.Equal(t, test.expectedErr.Error(), err.Error())
-			} else {
-				assert.Equal(t, test.expectedErr, err)
-			}
-
+			assert.Equal(t, test.expectedErr, err)
 			if err != nil {
 				return
 			}
diff --git a/usecases/traverser/traverser_schema_search_params_test.go b/usecases/traverser/traverser_schema_search_params_test.go
index c4c407c0f5..3942e735e0 100644
--- a/usecases/traverser/traverser_schema_search_params_test.go
+++ b/usecases/traverser/traverser_schema_search_params_test.go
@@ -102,11 +102,7 @@ func (s schemaSearchTests) AssertValidation(t *testing.T) {
 			err := test.searchParams.Validate()
 
 			// assert error
-			if test.expectedError != nil {
-				assert.Equal(t, test.expectedError.Error(), err.Error(), "should match the expected error")
-			} else {
-				assert.Equal(t, test.expectedError, err, "should match the expected error")
-			}
+			assert.Equal(t, test.expectedError, err, "should match the expected error")
 		})
 	}
 }