diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/Frames/Http3ErrorCode.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/Frames/Http3ErrorCode.cs
index fdfe04cee1580b..ebaa96f12cdc46 100644
--- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/Frames/Http3ErrorCode.cs
+++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/Frames/Http3ErrorCode.cs
@@ -91,5 +91,20 @@ internal enum Http3ErrorCode : long
         /// The requested operation cannot be served over HTTP/3. The peer should retry over HTTP/1.1.
         /// </summary>
         VersionFallback = 0x110,
+        /// <summary>
+        /// H3_QPACK_DECOMPRESSION_FAILED (0x200):
+        /// The decoder failed to interpret an encoded field section and is not able to continue decoding that field section.
+        /// </summary>
+        QPackDecompressionFailed = 0x200,
+        /// <summary>
+        /// H3_QPACK_ENCODER_STREAM_ERROR (0x201):
+        /// The decoder failed to interpret an encoder instruction received on the encoder stream.
+        /// </summary>
+        QPackEncoderStreamError = 0x201,
+        /// <summary>
+        /// H3_QPACK_DECODER_STREAM_ERROR (0x202):
+        /// The encoder failed to interpret an decoder instruction received on the decoder stream.
+        /// </summary>
+        QPackDecoderStreamError = 0x202,
     }
 }
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs
index 64ba4089d5dbca..ef2532b2b22d08 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs
@@ -277,8 +277,12 @@ await Task.WhenAny(sendRequestTask, readResponseTask).ConfigureAwait(false) == s
             }
             catch (QuicException ex) when (ex.QuicError == QuicError.OperationAborted && _connection.AbortException != null)
             {
-                // we close the connection, propagate the AbortException
-                throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_client_execution_error, _connection.AbortException);
+                // we closed the connection already, propagate the AbortException
+                HttpRequestError httpRequestError = _connection.AbortException is HttpProtocolException
+                    ? HttpRequestError.HttpProtocolError
+                    : HttpRequestError.Unknown;
+
+                throw new HttpRequestException(httpRequestError, SR.net_http_client_execution_error, _connection.AbortException);
             }
             // It is possible for user's Content code to throw an unexpected OperationCanceledException.
             catch (OperationCanceledException ex) when (ex.CancellationToken == _requestBodyCancellationSource.Token || ex.CancellationToken == cancellationToken)
@@ -300,6 +304,16 @@ await Task.WhenAny(sendRequestTask, readResponseTask).ConfigureAwait(false) == s
                 _connection.Abort(ex);
                 throw new HttpRequestException(ex.HttpRequestError, SR.net_http_client_execution_error, ex);
             }
+            catch (QPackDecodingException ex)
+            {
+                Exception abortException = _connection.Abort(HttpProtocolException.CreateHttp3ConnectionException(Http3ErrorCode.QPackDecompressionFailed));
+                throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.net_http_invalid_response, ex);
+            }
+            catch (QPackEncodingException ex)
+            {
+                _stream.Abort(QuicAbortDirection.Write, (long)Http3ErrorCode.InternalError);
+                throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_client_execution_error, ex);
+            }
             catch (Exception ex)
             {
                 _stream.Abort(QuicAbortDirection.Write, (long)Http3ErrorCode.InternalError);
@@ -307,6 +321,9 @@ await Task.WhenAny(sendRequestTask, readResponseTask).ConfigureAwait(false) == s
                 {
                     throw;
                 }
+
+                // all exceptions should be already handled above
+                Debug.Fail($"Unexpected exception type in Http3RequestStream.SendAsync: {ex}");
                 throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_client_execution_error, ex);
             }
             finally
@@ -1253,6 +1270,13 @@ private void HandleReadResponseContentException(Exception ex, CancellationToken
                     _connection.Abort(exception);
                     throw exception;
 
+                case QuicException e when (e.QuicError == QuicError.OperationAborted && _connection.AbortException != null):
+                    // we closed the connection already, propagate the AbortException
+                    HttpRequestError httpRequestError = _connection.AbortException is HttpProtocolException
+                        ? HttpRequestError.HttpProtocolError
+                        : HttpRequestError.Unknown;
+                    throw new HttpRequestException(httpRequestError, SR.net_http_client_execution_error, _connection.AbortException);
+
                 case HttpIOException:
                     _connection.Abort(ex);
                     ExceptionDispatchInfo.Throw(ex); // Rethrow.
diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs
index 16abc260386b42..5baccdd3785543 100644
--- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs
+++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs
@@ -35,7 +35,10 @@ private async Task AssertProtocolErrorAsync(long errorCode, Func<Task> task)
         {
             Exception outerEx = await Assert.ThrowsAnyAsync<Exception>(task);
             _output.WriteLine(outerEx.ToString());
-            Assert.IsType<HttpRequestException>(outerEx);
+
+            HttpRequestException httpReqException = Assert.IsType<HttpRequestException>(outerEx);
+            Assert.Equal(HttpRequestError.HttpProtocolError, httpReqException.HttpRequestError);
+
             HttpProtocolException protocolEx = Assert.IsType<HttpProtocolException>(outerEx.InnerException);
             Assert.Equal(errorCode, protocolEx.ErrorCode);
         }
@@ -1759,7 +1762,14 @@ public async Task ServerClosesOutboundControlStream_ClientClosesConnection(Close
                             return;
                         }
                         await connection.OutboundControlStream.DisposeAsync();
-                        await connection.EstablishControlStreamAsync(Array.Empty<SettingsEntry>());
+                        try
+                        {
+                            await connection.EstablishControlStreamAsync(Array.Empty<SettingsEntry>());
+                        }
+                        catch (QuicException ex) when (ex.QuicError == QuicError.ConnectionAborted && ex.ApplicationErrorCode == Http3LoopbackConnection.H3_CLOSED_CRITICAL_STREAM)
+                        {
+                            // Data race, connection closed between WaitAsync and EstablishControlStreamAsync. Ignore this.
+                        }
                         await Task.Delay(100);
                     }
                 }
