diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.cs b/src/libraries/System.Net.Http/ref/System.Net.Http.cs
index 3ac82158387eb4..a31f5e69ad8cf0 100644
--- a/src/libraries/System.Net.Http/ref/System.Net.Http.cs
+++ b/src/libraries/System.Net.Http/ref/System.Net.Http.cs
@@ -272,8 +272,8 @@ public HttpRequestException() { }
         public HttpRequestException(string? message) { }
         public HttpRequestException(string? message, System.Exception? inner) { }
         public HttpRequestException(string? message, System.Exception? inner, System.Net.HttpStatusCode? statusCode) { }
-        public HttpRequestException(string? message, System.Exception? inner = null, System.Net.HttpStatusCode? statusCode = null, System.Net.Http.HttpRequestError? httpRequestError = null) { }
-        public System.Net.Http.HttpRequestError? HttpRequestError { get { throw null; } }
+        public HttpRequestException(System.Net.Http.HttpRequestError httpRequestError, string? message = null, System.Exception? inner = null, System.Net.HttpStatusCode? statusCode = null) { }
+        public System.Net.Http.HttpRequestError HttpRequestError { get { throw null; } }
         public System.Net.HttpStatusCode? StatusCode { get { throw null; } }
     }
     public partial class HttpRequestMessage : System.IDisposable
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs
index b1cc357f32a355..2523829550e517 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs
@@ -4,6 +4,7 @@
 using System.Buffers;
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
 using System.IO;
 using System.Net.Http.Headers;
 using System.Text;
@@ -608,7 +609,7 @@ private bool CreateTemporaryBuffer(long maxBufferSize, out MemoryStream? tempBuf
                 // This should only be hit when called directly; HttpClient/HttpClientHandler
                 // will not exceed this limit.
                 throw new ArgumentOutOfRangeException(nameof(maxBufferSize), maxBufferSize,
-                    SR.Format(System.Globalization.CultureInfo.InvariantCulture,
+                    SR.Format(CultureInfo.InvariantCulture,
                         SR.net_http_content_buffersize_limit, HttpContent.MaxBufferSize));
             }
 
@@ -720,7 +721,7 @@ internal static Exception WrapStreamCopyException(Exception e)
         {
             Debug.Assert(StreamCopyExceptionNeedsWrapping(e));
             HttpRequestError error = e is HttpIOException ioEx ? ioEx.HttpRequestError : HttpRequestError.Unknown;
-            return new HttpRequestException(SR.net_http_content_stream_copy_error, e, httpRequestError: error);
+            return new HttpRequestException(error, SR.net_http_content_stream_copy_error, e);
         }
 
         private static int GetPreambleLength(ArraySegment<byte> buffer, Encoding encoding)
@@ -835,7 +836,7 @@ private static async Task<TResult> WaitAndReturnAsync<TState, TResult>(Task wait
 
         private static HttpRequestException CreateOverCapacityException(long maxBufferSize)
         {
-            return new HttpRequestException(SR.Format(System.Globalization.CultureInfo.InvariantCulture, SR.net_http_content_buffersize_exceeded, maxBufferSize), httpRequestError: HttpRequestError.ConfigurationLimitExceeded);
+            return new HttpRequestException(HttpRequestError.ConfigurationLimitExceeded, SR.Format(CultureInfo.InvariantCulture, SR.net_http_content_buffersize_exceeded, maxBufferSize));
         }
 
         internal sealed class LimitMemoryStream : MemoryStream
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestException.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestException.cs
index 5623387adfbee8..4ee9c11bc8639a 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestException.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestException.cs
@@ -38,11 +38,11 @@ public HttpRequestException(string? message, Exception? inner, HttpStatusCode? s
         /// <summary>
         /// Initializes a new instance of the <see cref="HttpRequestException" /> class with a specific message an inner exception, and an HTTP status code and an <see cref="HttpRequestError"/>.
         /// </summary>
+        /// <param name="httpRequestError">The <see cref="HttpRequestError"/> that caused the exception.</param>
         /// <param name="message">A message that describes the current exception.</param>
         /// <param name="inner">The inner exception.</param>
         /// <param name="statusCode">The HTTP status code.</param>
-        /// <param name="httpRequestError">The <see cref="HttpRequestError"/> that caused the exception.</param>
-        public HttpRequestException(string? message, Exception? inner = null, HttpStatusCode? statusCode = null, HttpRequestError? httpRequestError = null)
+        public HttpRequestException(HttpRequestError httpRequestError, string? message = null, Exception? inner = null, HttpStatusCode? statusCode = null)
             : this(message, inner, statusCode)
         {
             HttpRequestError = httpRequestError;
@@ -51,10 +51,7 @@ public HttpRequestException(string? message, Exception? inner = null, HttpStatus
         /// <summary>
         /// Gets the <see cref="Http.HttpRequestError"/> that caused the exception.
         /// </summary>
-        /// <value>
-        /// The <see cref="Http.HttpRequestError"/> or <see langword="null"/> if the underlying <see cref="HttpMessageHandler"/> did not provide it.
-        /// </value>
-        public HttpRequestError? HttpRequestError { get; }
+        public HttpRequestError HttpRequestError { get; }
 
         /// <summary>
         /// Gets the HTTP status code to be returned with the exception.
@@ -66,8 +63,8 @@ public HttpRequestException(string? message, Exception? inner = null, HttpStatus
 
         // This constructor is used internally to indicate that a request was not successfully sent due to an IOException,
         // and the exception occurred early enough so that the request may be retried on another connection.
-        internal HttpRequestException(string? message, Exception? inner, RequestRetryType allowRetry, HttpRequestError? httpRequestError = null)
-            : this(message, inner, httpRequestError: httpRequestError)
+        internal HttpRequestException(HttpRequestError httpRequestError, string? message, Exception? inner, RequestRetryType allowRetry)
+            : this(httpRequestError, message, inner)
         {
             AllowRetry = allowRetry;
         }
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs
index 7ac830be4b889a..eee8c617b5345e 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs
@@ -209,7 +209,7 @@ private static async Task<HttpResponseMessage> SendWithNtAuthAsync(HttpRequestMe
                                 {
                                     isNewConnection = false;
                                     connection.Dispose();
-                                    throw new HttpRequestException(SR.Format(SR.net_http_authvalidationfailure, statusCode), null, HttpStatusCode.Unauthorized, HttpRequestError.UserAuthenticationError);
+                                    throw new HttpRequestException(HttpRequestError.UserAuthenticationError, SR.Format(SR.net_http_authvalidationfailure, statusCode), statusCode: HttpStatusCode.Unauthorized);
                                 }
                                 break;
                             }
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs
index 2dbe558d971661..8bf0f39e0f63a9 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs
@@ -89,7 +89,7 @@ public static async ValueTask<SslStream> EstablishSslConnectionAsync(SslClientAu
                     throw CancellationHelper.CreateOperationCanceledException(e, cancellationToken);
                 }
 
-                HttpRequestException ex = new HttpRequestException(SR.net_http_ssl_connection_failed, e, httpRequestError: HttpRequestError.SecureConnectionError);
+                HttpRequestException ex = new HttpRequestException(HttpRequestError.SecureConnectionError, SR.net_http_ssl_connection_failed, e);
                 if (request.IsExtendedConnectRequest)
                 {
                     // Extended connect request is negotiating strictly for ALPN = "h2" because HttpClient is unaware of a possible downgrade.
@@ -139,7 +139,7 @@ internal static Exception CreateWrappedException(Exception exception, string hos
         {
             return CancellationHelper.ShouldWrapInOperationCanceledException(exception, cancellationToken) ?
                 CancellationHelper.CreateOperationCanceledException(exception, cancellationToken) :
-                new HttpRequestException($"{exception.Message} ({host}:{port})", exception, RequestRetryType.RetryOnNextProxy, DeduceError(exception));
+                new HttpRequestException(DeduceError(exception), $"{exception.Message} ({host}:{port})", exception, RequestRetryType.RetryOnNextProxy);
 
             static HttpRequestError DeduceError(Exception exception)
             {
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs
index 69563103e1e18f..8f3093de88e2c7 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs
@@ -2104,11 +2104,11 @@ await Task.WhenAny(requestBodyTask, responseHeadersTask).ConfigureAwait(false) =
             }
             catch (HttpIOException e)
             {
-                throw new HttpRequestException(e.Message, e, httpRequestError: e.HttpRequestError);
+                throw new HttpRequestException(e.HttpRequestError, e.Message, e);
             }
             catch (Exception e) when (e is IOException || e is ObjectDisposedException || e is InvalidOperationException)
             {
-                throw new HttpRequestException(SR.net_http_client_execution_error, e, httpRequestError: HttpRequestError.Unknown);
+                throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_client_execution_error, e);
             }
         }
 
@@ -2205,7 +2205,7 @@ internal void Trace(int streamId, string message, [CallerMemberName] string? mem
 
         [DoesNotReturn]
         private static void ThrowRetry(string message, Exception? innerException = null) =>
-            throw new HttpRequestException(message, innerException, allowRetry: RequestRetryType.RetryOnConnectionFailure);
+            throw new HttpRequestException(HttpRequestError.Unknown, message, innerException, RequestRetryType.RetryOnConnectionFailure);
 
         private static Exception GetRequestAbortedException(Exception? innerException = null) =>
             innerException as HttpIOException ?? new IOException(SR.net_http_request_aborted, innerException);
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs
index 2b770746218669..de66b7cfa103d2 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs
@@ -540,7 +540,7 @@ void IHttpStreamHeadersHandler.OnStaticIndexedHeader(int index)
                 if (index <= LastHPackRequestPseudoHeaderId)
                 {
                     if (NetEventSource.Log.IsEnabled()) Trace($"Invalid request pseudo-header ID {index}.");
-                    throw new HttpRequestException(SR.net_http_invalid_response, httpRequestError: HttpRequestError.InvalidResponse);
+                    throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.net_http_invalid_response);
                 }
                 else if (index <= LastHPackStatusPseudoHeaderId)
                 {
@@ -563,7 +563,7 @@ void IHttpStreamHeadersHandler.OnStaticIndexedHeader(int index, ReadOnlySpan<byt
                 if (index <= LastHPackRequestPseudoHeaderId)
                 {
                     if (NetEventSource.Log.IsEnabled()) Trace($"Invalid request pseudo-header ID {index}.");
-                    throw new HttpRequestException(SR.net_http_invalid_response, httpRequestError: HttpRequestError.InvalidResponse);
+                    throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.net_http_invalid_response);
                 }
                 else if (index <= LastHPackStatusPseudoHeaderId)
                 {
@@ -589,7 +589,7 @@ private void AdjustHeaderBudget(int amount)
                 _headerBudgetRemaining -= amount;
                 if (_headerBudgetRemaining < 0)
                 {
-                    throw new HttpRequestException(SR.Format(SR.net_http_response_headers_exceeded_length, _connection._pool.Settings.MaxResponseHeadersByteLength), httpRequestError: HttpRequestError.ConfigurationLimitExceeded);
+                    throw new HttpRequestException(HttpRequestError.ConfigurationLimitExceeded, SR.Format(SR.net_http_response_headers_exceeded_length, _connection._pool.Settings.MaxResponseHeadersByteLength));
                 }
             }
 
@@ -611,14 +611,14 @@ private void OnStatus(int statusCode)
                     if (_responseProtocolState == ResponseProtocolState.ExpectingHeaders)
                     {
                         if (NetEventSource.Log.IsEnabled()) Trace("Received extra status header.");
-                        throw new HttpRequestException(SR.net_http_invalid_response_multiple_status_codes, httpRequestError: HttpRequestError.ConfigurationLimitExceeded);
+                        throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.net_http_invalid_response_multiple_status_codes);
                     }
 
                     if (_responseProtocolState != ResponseProtocolState.ExpectingStatus)
                     {
                         // Pseudo-headers are allowed only in header block
                         if (NetEventSource.Log.IsEnabled()) Trace($"Status pseudo-header received in {_responseProtocolState} state.");
-                        throw new HttpRequestException(SR.net_http_invalid_response_pseudo_header_in_trailer, httpRequestError: HttpRequestError.InvalidResponse);
+                        throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.net_http_invalid_response_pseudo_header_in_trailer);
                     }
 
                     Debug.Assert(_response != null);
@@ -681,7 +681,7 @@ private void OnHeader(HeaderDescriptor descriptor, ReadOnlySpan<byte> value)
                     if (_responseProtocolState != ResponseProtocolState.ExpectingHeaders && _responseProtocolState != ResponseProtocolState.ExpectingTrailingHeaders)
                     {
                         if (NetEventSource.Log.IsEnabled()) Trace("Received header before status.");
-                        throw new HttpRequestException(SR.net_http_invalid_response, httpRequestError: HttpRequestError.InvalidResponse);
+                        throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.net_http_invalid_response);
                     }
 
                     Encoding? valueEncoding = _connection._pool.Settings._responseHeaderEncodingSelector?.Invoke(descriptor.Name, _request);
@@ -725,7 +725,7 @@ public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)
                     else
                     {
                         if (NetEventSource.Log.IsEnabled()) Trace($"Invalid response pseudo-header '{Encoding.ASCII.GetString(name)}'.");
-                        throw new HttpRequestException(SR.net_http_invalid_response, httpRequestError: HttpRequestError.InvalidResponse);
+                        throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.net_http_invalid_response);
                     }
                 }
                 else
@@ -734,7 +734,7 @@ public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)
                     if (!HeaderDescriptor.TryGet(name, out HeaderDescriptor descriptor))
                     {
                         // Invalid header name
-                        throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_header_name, Encoding.ASCII.GetString(name)), httpRequestError: HttpRequestError.InvalidResponse);
+                        throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.Format(SR.net_http_invalid_response_header_name, Encoding.ASCII.GetString(name)));
                     }
 
                     OnHeader(descriptor, value);
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs
index 2c6984162e55be..9744d02fc94f85 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs
@@ -208,7 +208,7 @@ public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, lon
 
                 if (quicStream == null)
                 {
-                    throw new HttpRequestException(SR.net_http_request_aborted, null, RequestRetryType.RetryOnConnectionFailure);
+                    throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_request_aborted, null, RequestRetryType.RetryOnConnectionFailure);
                 }
 
                 requestStream!.StreamId = quicStream.Id;
@@ -221,7 +221,7 @@ public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, lon
 
                 if (goAway)
                 {
-                    throw new HttpRequestException(SR.net_http_request_aborted, null, RequestRetryType.RetryOnConnectionFailure);
+                    throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_request_aborted, null, RequestRetryType.RetryOnConnectionFailure);
                 }
 
                 if (NetEventSource.Log.IsEnabled()) Trace($"Sending request: {request}");
@@ -237,7 +237,7 @@ public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, lon
             {
                 // This will happen if we aborted _connection somewhere and we have pending OpenOutboundStreamAsync call.
                 // note that _abortException may be null if we closed the connection in response to a GOAWAY frame
-                throw new HttpRequestException(SR.net_http_client_execution_error, _abortException, RequestRetryType.RetryOnConnectionFailure);
+                throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_client_execution_error, _abortException, RequestRetryType.RetryOnConnectionFailure);
             }
             finally
             {
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 828e0bb2ffc7e8..f5e037cf1d4067 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
@@ -252,18 +252,18 @@ await Task.WhenAny(sendContentTask, readResponseTask).ConfigureAwait(false) == s
                 {
                     case Http3ErrorCode.VersionFallback:
                         // The server is requesting us fall back to an older HTTP version.
-                        throw new HttpRequestException(SR.net_http_retry_on_older_version, ex, RequestRetryType.RetryOnLowerHttpVersion);
+                        throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_retry_on_older_version, ex, RequestRetryType.RetryOnLowerHttpVersion);
 
                     case Http3ErrorCode.RequestRejected:
                         // The server is rejecting the request without processing it, retry it on a different connection.
                         HttpProtocolException rejectedException = HttpProtocolException.CreateHttp3StreamException(code, ex);
-                        throw new HttpRequestException(SR.net_http_request_aborted, rejectedException, RequestRetryType.RetryOnConnectionFailure, httpRequestError: HttpRequestError.HttpProtocolError);
+                        throw new HttpRequestException(HttpRequestError.HttpProtocolError, SR.net_http_request_aborted, rejectedException, RequestRetryType.RetryOnConnectionFailure);
 
                     default:
                         // Our stream was reset.
                         Exception innerException = _connection.AbortException ?? HttpProtocolException.CreateHttp3StreamException(code, ex);
                         HttpRequestError httpRequestError = innerException is HttpProtocolException ? HttpRequestError.HttpProtocolError : HttpRequestError.Unknown;
-                        throw new HttpRequestException(SR.net_http_client_execution_error, innerException, httpRequestError: httpRequestError);
+                        throw new HttpRequestException(httpRequestError, SR.net_http_client_execution_error, innerException);
                 }
             }
             catch (QuicException ex) when (ex.QuicError == QuicError.ConnectionAborted)
@@ -273,12 +273,12 @@ await Task.WhenAny(sendContentTask, readResponseTask).ConfigureAwait(false) == s
                 Http3ErrorCode code = (Http3ErrorCode)ex.ApplicationErrorCode.Value;
 
                 Exception abortException = _connection.Abort(HttpProtocolException.CreateHttp3ConnectionException(code, SR.net_http_http3_connection_close));
-                throw new HttpRequestException(SR.net_http_client_execution_error, abortException, httpRequestError: HttpRequestError.HttpProtocolError);
+                throw new HttpRequestException(HttpRequestError.HttpProtocolError, SR.net_http_client_execution_error, abortException);
             }
             catch (QuicException ex) when (ex.QuicError == QuicError.OperationAborted && _connection.AbortException != null)
             {
                 // we close the connection, propagate the AbortException
-                throw new HttpRequestException(SR.net_http_client_execution_error, _connection.AbortException, httpRequestError: HttpRequestError.Unknown);
+                throw new HttpRequestException(HttpRequestError.Unknown, 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)
@@ -292,13 +292,13 @@ await Task.WhenAny(sendContentTask, readResponseTask).ConfigureAwait(false) == s
                 else
                 {
                     Debug.Assert(_requestBodyCancellationSource.IsCancellationRequested);
-                    throw new HttpRequestException(SR.net_http_request_aborted, ex, RequestRetryType.RetryOnConnectionFailure, httpRequestError: HttpRequestError.Unknown);
+                    throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_request_aborted, ex, RequestRetryType.RetryOnConnectionFailure);
                 }
             }
             catch (HttpIOException ex)
             {
                 _connection.Abort(ex);
-                throw new HttpRequestException(SR.net_http_client_execution_error, ex, httpRequestError: ex.HttpRequestError);
+                throw new HttpRequestException(ex.HttpRequestError, SR.net_http_client_execution_error, ex);
             }
             catch (Exception ex)
             {
@@ -307,7 +307,7 @@ await Task.WhenAny(sendContentTask, readResponseTask).ConfigureAwait(false) == s
                 {
                     throw;
                 }
-                throw new HttpRequestException(SR.net_http_client_execution_error, ex, httpRequestError: HttpRequestError.Unknown);
+                throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_client_execution_error, ex);
             }
             finally
             {
@@ -870,7 +870,7 @@ private async ValueTask ReadHeadersAsync(long headersLength, CancellationToken c
             if (headersLength > _headerBudgetRemaining)
             {
                 _stream.Abort(QuicAbortDirection.Read, (long)Http3ErrorCode.ExcessiveLoad);
-                throw new HttpRequestException(SR.Format(SR.net_http_response_headers_exceeded_length, _connection.Pool.Settings.MaxResponseHeadersByteLength), httpRequestError: HttpRequestError.ConfigurationLimitExceeded);
+                throw new HttpRequestException(HttpRequestError.ConfigurationLimitExceeded, SR.Format(SR.net_http_response_headers_exceeded_length, _connection.Pool.Settings.MaxResponseHeadersByteLength));
             }
 
             _headerBudgetRemaining -= (int)headersLength;
@@ -911,7 +911,7 @@ void IHttpStreamHeadersHandler.OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<by
             if (!HeaderDescriptor.TryGet(name, out HeaderDescriptor descriptor))
             {
                 // Invalid header name
-                throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_header_name, Encoding.ASCII.GetString(name)), httpRequestError: HttpRequestError.InvalidResponse);
+                throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.Format(SR.net_http_invalid_response_header_name, Encoding.ASCII.GetString(name)));
             }
             OnHeader(staticIndex: null, descriptor, staticValue: default, literalValue: value);
         }
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
index 5fc58bf67fc3ef..617dd466ef1df0 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
@@ -882,19 +882,23 @@ private bool MapSendException(Exception exception, CancellationToken cancellatio
                 mappedException = CancellationHelper.CreateOperationCanceledException(exception, cancellationToken);
                 return true;
             }
+
             if (exception is InvalidOperationException)
             {
                 // For consistency with other handlers we wrap the exception in an HttpRequestException.
                 mappedException = new HttpRequestException(SR.net_http_client_execution_error, exception);
                 return true;
             }
+
             if (exception is IOException ioe)
             {
                 // For consistency with other handlers we wrap the exception in an HttpRequestException.
                 // If the request is retryable, indicate that on the exception.
-                mappedException = new HttpRequestException(SR.net_http_client_execution_error, ioe, _canRetry ? RequestRetryType.RetryOnConnectionFailure : RequestRetryType.NoRetry);
+                HttpRequestError error = ioe is HttpIOException httpIoe ? httpIoe.HttpRequestError : HttpRequestError.Unknown;
+                mappedException = new HttpRequestException(error, SR.net_http_client_execution_error, ioe, _canRetry ? RequestRetryType.RetryOnConnectionFailure : RequestRetryType.NoRetry);
                 return true;
             }
+
             // Otherwise, just allow the original exception to propagate.
             mappedException = exception;
             return false;
@@ -1023,7 +1027,7 @@ private static void ParseStatusLineCore(Span<byte> line, HttpResponseMessage res
             const int MinStatusLineLength = 12; // "HTTP/1.x 123"
             if (line.Length < MinStatusLineLength || line[8] != ' ')
             {
-                throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_status_line, Encoding.ASCII.GetString(line)), httpRequestError: HttpRequestError.InvalidResponse);
+                throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.Format(SR.net_http_invalid_response_status_line, Encoding.ASCII.GetString(line)));
             }
 
             ulong first8Bytes = BitConverter.ToUInt64(line);
@@ -1044,7 +1048,7 @@ private static void ParseStatusLineCore(Span<byte> line, HttpResponseMessage res
                 }
                 else
                 {
-                    throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_status_line, Encoding.ASCII.GetString(line)), httpRequestError: HttpRequestError.InvalidResponse);
+                    throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.Format(SR.net_http_invalid_response_status_line, Encoding.ASCII.GetString(line)));
                 }
             }
 
@@ -1052,7 +1056,7 @@ private static void ParseStatusLineCore(Span<byte> line, HttpResponseMessage res
             byte status1 = line[9], status2 = line[10], status3 = line[11];
             if (!IsDigit(status1) || !IsDigit(status2) || !IsDigit(status3))
             {
-                throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_status_code, Encoding.ASCII.GetString(line.Slice(9, 3))), httpRequestError: HttpRequestError.InvalidResponse);
+                throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.Format(SR.net_http_invalid_response_status_code, Encoding.ASCII.GetString(line.Slice(9, 3))));
             }
             response.SetStatusCodeWithoutValidation((HttpStatusCode)(100 * (status1 - '0') + 10 * (status2 - '0') + (status3 - '0')));
 
@@ -1077,13 +1081,13 @@ private static void ParseStatusLineCore(Span<byte> line, HttpResponseMessage res
                     }
                     catch (FormatException formatEx)
                     {
-                        throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_status_reason, Encoding.ASCII.GetString(reasonBytes.ToArray())), formatEx, httpRequestError: HttpRequestError.InvalidResponse);
+                        throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.Format(SR.net_http_invalid_response_status_reason, Encoding.ASCII.GetString(reasonBytes.ToArray())), formatEx);
                     }
                 }
             }
             else
             {
-                throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_status_line, Encoding.ASCII.GetString(line)), httpRequestError: HttpRequestError.InvalidResponse);
+                throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.Format(SR.net_http_invalid_response_status_line, Encoding.ASCII.GetString(line)));
             }
         }
 
@@ -1182,7 +1186,7 @@ private bool ParseHeaders(HttpResponseMessage? response, bool isFromTrailer)
             }
 
             static void ThrowForInvalidHeaderLine(ReadOnlySpan<byte> buffer, int newLineIndex) =>
-                throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_header_line, Encoding.ASCII.GetString(buffer.Slice(0, newLineIndex))), httpRequestError: HttpRequestError.InvalidResponse);
+                throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.Format(SR.net_http_invalid_response_header_line, Encoding.ASCII.GetString(buffer.Slice(0, newLineIndex))));
         }
 
         private void AddResponseHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value, HttpResponseMessage response, bool isFromTrailer)
@@ -1281,14 +1285,14 @@ private void AddResponseHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value
             Debug.Assert(added);
 
             static void ThrowForEmptyHeaderName() =>
-                throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_header_name, ""), httpRequestError: HttpRequestError.InvalidResponse);
+                throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.Format(SR.net_http_invalid_response_header_name, ""));
 
             static void ThrowForInvalidHeaderName(ReadOnlySpan<byte> name) =>
-                throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_header_name, Encoding.ASCII.GetString(name)), httpRequestError: HttpRequestError.InvalidResponse);
+                throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.Format(SR.net_http_invalid_response_header_name, Encoding.ASCII.GetString(name)));
         }
 
         private void ThrowExceededAllowedReadLineBytes() =>
-            throw new HttpRequestException(SR.Format(SR.net_http_response_headers_exceeded_length, _pool.Settings.MaxResponseHeadersByteLength), httpRequestError: HttpRequestError.ConfigurationLimitExceeded);
+            throw new HttpRequestException(HttpRequestError.ConfigurationLimitExceeded, SR.Format(SR.net_http_response_headers_exceeded_length, _pool.Settings.MaxResponseHeadersByteLength));
 
         private void ProcessKeepAliveHeader(string keepAlive)
         {
@@ -2023,7 +2027,7 @@ public async ValueTask DrainResponseAsync(HttpResponseMessage response, Cancella
 
             if (_connectionClose)
             {
-                throw new HttpRequestException(SR.net_http_authconnectionfailure, httpRequestError: HttpRequestError.UserAuthenticationError);
+                throw new HttpRequestException(HttpRequestError.UserAuthenticationError, SR.net_http_authconnectionfailure);
             }
 
             Debug.Assert(response.Content != null);
@@ -2039,7 +2043,7 @@ public async ValueTask DrainResponseAsync(HttpResponseMessage response, Cancella
                 if (!await responseStream.DrainAsync(_pool.Settings._maxResponseDrainSize).ConfigureAwait(false) ||
                     _connectionClose)       // Draining may have set this
                 {
-                    throw new HttpRequestException(SR.net_http_authconnectionfailure, httpRequestError: HttpRequestError.UserAuthenticationError);
+                    throw new HttpRequestException(HttpRequestError.UserAuthenticationError, SR.net_http_authconnectionfailure);
                 }
             }
 
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs
index ed5091ec06f2f6..f44c893f8f53d5 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs
@@ -164,7 +164,7 @@ internal static int ParseStatusCode(ReadOnlySpan<byte> value)
                 !IsDigit(status2 = value[1]) ||
                 !IsDigit(status3 = value[2]))
             {
-                throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_status_code, System.Text.Encoding.ASCII.GetString(value)), httpRequestError: HttpRequestError.InvalidResponse);
+                throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.Format(SR.net_http_invalid_response_status_code, Encoding.ASCII.GetString(value)));
             }
 
             return 100 * (status1 - '0') + 10 * (status2 - '0') + (status3 - '0');
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs
index de967c4e769a7e..5e98fc1cdcad93 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs
@@ -448,7 +448,7 @@ private static void ThrowGetVersionException(HttpRequestMessage request, int des
         {
             Debug.Assert(desiredVersion == 2 || desiredVersion == 3);
 
-            HttpRequestException ex = new(SR.Format(SR.net_http_requested_version_cannot_establish, request.Version, request.VersionPolicy, desiredVersion), inner, httpRequestError: HttpRequestError.VersionNegotiationError);
+            HttpRequestException ex = new(HttpRequestError.VersionNegotiationError, SR.Format(SR.net_http_requested_version_cannot_establish, request.Version, request.VersionPolicy, desiredVersion), inner);
             if (request.IsExtendedConnectRequest && desiredVersion == 2)
             {
                 ex.Data["HTTP2_ENABLED"] = false;
@@ -1095,7 +1095,7 @@ public async ValueTask<HttpResponseMessage> SendWithVersionDetectionAndRetryAsyn
                                     await connection.InitialSettingsReceived.WaitWithCancellationAsync(cancellationToken).ConfigureAwait(false);
                                     if (!connection.IsConnectEnabled)
                                     {
-                                        HttpRequestException exception = new(SR.net_unsupported_extended_connect, httpRequestError: HttpRequestError.ExtendedConnectNotSupported);
+                                        HttpRequestException exception = new(HttpRequestError.ExtendedConnectNotSupported, SR.net_unsupported_extended_connect);
                                         exception.Data["SETTINGS_ENABLE_CONNECT_PROTOCOL"] = false;
                                         throw exception;
                                     }
@@ -1162,7 +1162,7 @@ public async ValueTask<HttpResponseMessage> SendWithVersionDetectionAndRetryAsyn
                     // Throw if fallback is not allowed by the version policy.
                     if (request.VersionPolicy != HttpVersionPolicy.RequestVersionOrLower)
                     {
-                        throw new HttpRequestException(SR.Format(SR.net_http_requested_version_server_refused, request.Version, request.VersionPolicy), e, httpRequestError: HttpRequestError.VersionNegotiationError);
+                        throw new HttpRequestException(HttpRequestError.VersionNegotiationError, SR.Format(SR.net_http_requested_version_server_refused, request.Version, request.VersionPolicy), e);
                     }
 
                     if (NetEventSource.Log.IsEnabled())
@@ -1775,7 +1775,7 @@ private async ValueTask<Stream> EstablishProxyTunnelAsync(bool async, Cancellati
             if (tunnelResponse.StatusCode != HttpStatusCode.OK)
             {
                 tunnelResponse.Dispose();
-                throw new HttpRequestException(SR.Format(SR.net_http_proxy_tunnel_returned_failure_status_code, _proxyUri, (int)tunnelResponse.StatusCode), httpRequestError: HttpRequestError.ProxyTunnelError);
+                throw new HttpRequestException(HttpRequestError.ProxyTunnelError, SR.Format(SR.net_http_proxy_tunnel_returned_failure_status_code, _proxyUri, (int)tunnelResponse.StatusCode));
             }
 
             try
@@ -1802,7 +1802,7 @@ private async ValueTask<Stream> EstablishSocksTunnel(HttpRequestMessage request,
             catch (Exception e) when (!(e is OperationCanceledException))
             {
                 Debug.Assert(!(e is HttpRequestException));
-                throw new HttpRequestException(SR.net_http_proxy_tunnel_error, e, httpRequestError: HttpRequestError.ProxyTunnelError);
+                throw new HttpRequestException(HttpRequestError.ProxyTunnelError, SR.net_http_proxy_tunnel_error, e);
             }
 
             return stream;
diff --git a/src/libraries/System.Net.Http/tests/UnitTests/HttpRequestExceptionTests.cs b/src/libraries/System.Net.Http/tests/UnitTests/HttpRequestExceptionTests.cs
index eadba6eca1a312..2eedfcd575f4b8 100644
--- a/src/libraries/System.Net.Http/tests/UnitTests/HttpRequestExceptionTests.cs
+++ b/src/libraries/System.Net.Http/tests/UnitTests/HttpRequestExceptionTests.cs
@@ -35,5 +35,20 @@ public void StoresNonStandardStatusCode()
             var exception = new HttpRequestException("message", null, statusCode);
             Assert.Equal(statusCode, exception.StatusCode);
         }
+
+        [Fact]
+        public void DefaultsToRequestErrorUnknown()
+        {
+            Assert.Equal(HttpRequestError.Unknown, new HttpRequestException().HttpRequestError);
+        }
+
+        [Fact]
+        public void StoresNonStandardRequestError()
+        {
+            var requestError = (HttpRequestError)999;
+
+            var exception = new HttpRequestException(requestError);
+            Assert.Equal(requestError, exception.HttpRequestError);
+        }
     }
 }
