diff --git a/workhorse/gitaly_test.go b/workhorse/gitaly_test.go
index 270c40cb4bca1b6c9c37e0574b8743fde017294d..db3b76787aa42a53cbcf52dfa5b4c18d901afe46 100644
--- a/workhorse/gitaly_test.go
+++ b/workhorse/gitaly_test.go
@@ -17,11 +17,11 @@ import (
 	"testing"
 	"time"
 
-	"github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868
-	"github.com/golang/protobuf/proto"  //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868
 	"github.com/stretchr/testify/require"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
+	"google.golang.org/protobuf/encoding/protojson"
+	"google.golang.org/protobuf/proto"
 
 	"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
 
@@ -107,7 +107,7 @@ func TestGetInfoRefsProxiedToGitalySuccessfully(t *testing.T) {
 			require.Len(t, bodySplit, 3)
 
 			gitalyRequest := &gitalypb.InfoRefsRequest{}
-			require.NoError(t, jsonpb.UnmarshalString(bodySplit[0], gitalyRequest))
+			require.NoError(t, protojson.Unmarshal([]byte(bodySplit[0]), gitalyRequest))
 
 			require.Equal(t, gitProtocol, gitalyRequest.GitProtocol)
 			if tc.showAllRefs {
@@ -263,7 +263,7 @@ func TestPostReceivePackProxiedToGitalySuccessfully(t *testing.T) {
 	require.Len(t, split, 2)
 
 	gitalyRequest := &gitalypb.PostReceivePackRequest{}
-	require.NoError(t, jsonpb.UnmarshalString(split[0], gitalyRequest))
+	require.NoError(t, protojson.Unmarshal([]byte(split[0]), gitalyRequest))
 
 	require.Equal(t, apiResponse.Repository.StorageName, gitalyRequest.Repository.StorageName)
 	require.Equal(t, apiResponse.Repository.RelativePath, gitalyRequest.Repository.RelativePath)
@@ -437,7 +437,7 @@ func TestPostUploadPackProxiedToGitalySuccessfully(t *testing.T) {
 			require.Len(t, bodySplit, 2)
 
 			gitalyRequest := &gitalypb.PostUploadPackWithSidechannelRequest{}
-			require.NoError(t, jsonpb.UnmarshalString(bodySplit[0], gitalyRequest))
+			require.NoError(t, protojson.Unmarshal([]byte(bodySplit[0]), gitalyRequest))
 
 			require.Equal(t, apiResponse.Repository.StorageName, gitalyRequest.Repository.StorageName)
 			require.Equal(t, apiResponse.Repository.RelativePath, gitalyRequest.Repository.RelativePath)
@@ -822,13 +822,12 @@ func buildPbRepo(storageName, relativePath string) *gitalypb.Repository {
 }
 
 func serializedMessage(name string, arg proto.Message) rpcArg {
-	m := &jsonpb.Marshaler{}
-	str, err := m.MarshalToString(arg)
+	data, err := protojson.Marshal(arg)
 	if err != nil {
 		panic(err)
 	}
 
-	return rpcArg{name, str}
+	return rpcArg{name, string(data)}
 }
 
 func serializedProtoMessage(name string, arg proto.Message) rpcArg {
diff --git a/workhorse/go.mod b/workhorse/go.mod
index 8afe0f049aaf421c1bf879ed1a2a6d8a33691dd0..00fddbe2323ec969832e40b7f3786319978ecd3d 100644
--- a/workhorse/go.mod
+++ b/workhorse/go.mod
@@ -11,7 +11,6 @@ require (
 	github.com/getsentry/raven-go v0.2.0
 	github.com/golang-jwt/jwt/v5 v5.0.0
 	github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f
-	github.com/golang/protobuf v1.5.3
 	github.com/gorilla/websocket v1.5.0
 	github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
 	github.com/johannesboyne/gofakes3 v0.0.0-20230914150226-f005f5cc03aa
@@ -68,6 +67,7 @@ require (
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
+	github.com/golang/protobuf v1.5.3 // indirect
 	github.com/google/go-cmp v0.5.9 // indirect
 	github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect
 	github.com/google/s2a-go v0.1.4 // indirect
diff --git a/workhorse/internal/git/archive.go b/workhorse/internal/git/archive.go
index acccd93703816ff270b30cc43ebd88fb4172000f..58048c3183467977194502664f54eace0d09fd77 100644
--- a/workhorse/internal/git/archive.go
+++ b/workhorse/internal/git/archive.go
@@ -14,7 +14,7 @@ import (
 	"regexp"
 	"time"
 
-	"github.com/golang/protobuf/proto" //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868
+	"google.golang.org/protobuf/proto"
 
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/prometheus/client_golang/prometheus/promauto"
diff --git a/workhorse/internal/gitaly/gitaly.go b/workhorse/internal/gitaly/gitaly.go
index e4fbad170178c65e57d6a2c3abfd32713996806a..98f73b40a9d51e60b9de59f5ef3aa8991073f912 100644
--- a/workhorse/internal/gitaly/gitaly.go
+++ b/workhorse/internal/gitaly/gitaly.go
@@ -5,14 +5,14 @@ import (
 	"strings"
 	"sync"
 
-	"github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868
-	"github.com/golang/protobuf/proto"  //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868
 	grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/prometheus/client_golang/prometheus/promauto"
 	"github.com/sirupsen/logrus"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+	"google.golang.org/protobuf/proto"
 
 	gitalyauth "gitlab.com/gitlab-org/gitaly/v16/auth"
 	gitalyclient "gitlab.com/gitlab-org/gitaly/v16/client"
@@ -38,7 +38,6 @@ type connectionsCache struct {
 }
 
 var (
-	jsonUnMarshaler = jsonpb.Unmarshaler{AllowUnknownFields: true}
 	// This connection cache map contains two types of connections:
 	// - Normal gRPC connections
 	// - Sidechannel connections. When client dials to the Gitaly server, the
@@ -201,5 +200,5 @@ func newConnection(server api.GitalyServer) (*grpc.ClientConn, error) {
 }
 
 func UnmarshalJSON(s string, msg proto.Message) error {
-	return jsonUnMarshaler.Unmarshal(strings.NewReader(s), msg)
+	return protojson.UnmarshalOptions{DiscardUnknown: true}.Unmarshal([]byte(s), msg)
 }
diff --git a/workhorse/internal/gitaly/unmarshal_test.go b/workhorse/internal/gitaly/unmarshal_test.go
index 39e3a3f2502d1979bf834caff927fe1c87712380..bd9d5dc3bd57d90c77be4d1b595eb85c854620d5 100644
--- a/workhorse/internal/gitaly/unmarshal_test.go
+++ b/workhorse/internal/gitaly/unmarshal_test.go
@@ -3,9 +3,9 @@ package gitaly
 import (
 	"testing"
 
-	"github.com/golang/protobuf/proto" //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868
 	"github.com/stretchr/testify/require"
 	"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
+	"google.golang.org/protobuf/proto"
 )
 
 func TestUnmarshalJSON(t *testing.T) {
diff --git a/workhorse/internal/testhelper/gitaly.go b/workhorse/internal/testhelper/gitaly.go
index b468f0941de7646cc6660d37684e75891d2ea973..e8f30a043f7535724daee6e511cca9a4ac308666 100644
--- a/workhorse/internal/testhelper/gitaly.go
+++ b/workhorse/internal/testhelper/gitaly.go
@@ -9,8 +9,6 @@ import (
 	"strings"
 	"sync"
 
-	"github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868
-	"github.com/golang/protobuf/proto"  //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868
 	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
@@ -18,6 +16,8 @@ import (
 	"google.golang.org/grpc/credentials/insecure"
 	"google.golang.org/grpc/metadata"
 	"google.golang.org/grpc/status"
+	"google.golang.org/protobuf/encoding/protojson"
+	"google.golang.org/protobuf/proto"
 
 	"gitlab.com/gitlab-org/gitaly/v16/client"
 	"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
@@ -71,8 +71,7 @@ func (s *GitalyTestServer) InfoRefsUploadPack(in *gitalypb.InfoRefsRequest, stre
 
 	fmt.Printf("Result: %+v\n", in)
 
-	marshaler := &jsonpb.Marshaler{}
-	jsonString, err := marshaler.MarshalToString(in)
+	jsonString, err := marshalJSON(in)
 	if err != nil {
 		return err
 	}
@@ -116,8 +115,11 @@ func (s *GitalyTestServer) InfoRefsReceivePack(in *gitalypb.InfoRefsRequest, str
 }
 
 func marshalJSON(msg proto.Message) (string, error) {
-	marshaler := &jsonpb.Marshaler{}
-	return marshaler.MarshalToString(msg)
+	b, err := protojson.Marshal(msg)
+	if err != nil {
+		return "", err
+	}
+	return string(b), nil
 }
 
 type infoRefsSender interface {
@@ -198,14 +200,13 @@ func (s *GitalyTestServer) PostUploadPackWithSidechannel(ctx context.Context, re
 	}
 	defer conn.Close()
 
-	marshaler := &jsonpb.Marshaler{}
-	jsonBytes := &bytes.Buffer{}
-	if err := marshaler.Marshal(jsonBytes, req); err != nil {
+	jsonBytes, err := protojson.Marshal(req)
+	if err != nil {
 		return nil, err
 	}
 
 	if _, err := io.Copy(conn, io.MultiReader(
-		bytes.NewReader(append(jsonBytes.Bytes(), 0)),
+		bytes.NewReader(append(jsonBytes, 0)),
 		conn,
 	)); err != nil {
 		return nil, err