gfe-relnote: Send IETF QUIC, HTTP/3 and QPACK error codes in CONNECTION_CLOSE frames.  Protected by gfe2_reloadable_flag_quic_enable_version_draft_25_v3 and gfe2_reloadable_flag_quic_enable_version_draft_27.

Map each QuicErrorCode to an appropriate IETF error code.  QuicErrorCodes that
are never used, or not used with CONNECTION_CLOSE frames (only internally or
only with GOAWAY frames) are mapped to INTERNAL_ERROR.  Add test to enforce that
mapped error codes are valid transport or application error codes.

PiperOrigin-RevId: 305018830
Change-Id: Ia8a9bf848c56509a480a50017a7a7080593b11ee
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index d274c6c..71becf3 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -7625,7 +7625,7 @@
   QuicConnectionCloseFrame close_frame(
       framer_.transport_version(),
       static_cast<QuicErrorCode>(
-          VersionHasIetfQuicFrames(framer_.transport_version()) ? 0x11
+          VersionHasIetfQuicFrames(framer_.transport_version()) ? 0x01
                                                                 : 0x05060708),
       "because I can", 0x05);
   // Set this so that it is "there" for both Google QUIC and IETF QUIC
@@ -7687,8 +7687,9 @@
 
     // frame type (IETF_CONNECTION_CLOSE frame)
     0x1c,
-    // error code
-    kVarInt62OneByte + 0x11,
+    // IETF error code INTERNAL_ERROR = 0x01 corresponding to
+    // QuicErrorCode::QUIC_INTERNAL_ERROR = 0x01.
+    kVarInt62OneByte + 0x01,
     // Frame type within the CONNECTION_CLOSE frame
     kVarInt62OneByte + 0x05,
     // error details length
diff --git a/quic/core/quic_types.cc b/quic/core/quic_types.cc
index ce24d57..38775b2 100644
--- a/quic/core/quic_types.cc
+++ b/quic/core/quic_types.cc
@@ -132,303 +132,244 @@
 QuicErrorCodeToIetfMapping QuicErrorCodeToTransportErrorCode(
     QuicErrorCode error) {
   switch (error) {
-    // TODO(fkastenholz): Currently, all QuicError codes will map
-    // to application error codes and the original Google QUIC error
-    // code. This will change over time as we go through all calls to
-    // CloseConnection() and see whether the call is a Transport or an
-    // Application close and what the translated code should be.
     case QUIC_NO_ERROR:
-      return {true, {static_cast<uint64_t>(QUIC_NO_ERROR)}};
+      return {true, {static_cast<uint64_t>(NO_IETF_QUIC_ERROR)}};
     case QUIC_INTERNAL_ERROR:
-      return {true, {static_cast<uint64_t>(QUIC_INTERNAL_ERROR)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_STREAM_DATA_AFTER_TERMINATION:
-      return {true,
-              {static_cast<uint64_t>(QUIC_STREAM_DATA_AFTER_TERMINATION)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_INVALID_PACKET_HEADER:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_PACKET_HEADER)}};
+      return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}};
     case QUIC_INVALID_FRAME_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_FRAME_DATA)}};
+      return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}};
     case QUIC_MISSING_PAYLOAD:
-      return {true, {static_cast<uint64_t>(QUIC_MISSING_PAYLOAD)}};
+      return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}};
     case QUIC_INVALID_FEC_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_FEC_DATA)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_INVALID_STREAM_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_STREAM_DATA)}};
+      return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}};
     case QUIC_OVERLAPPING_STREAM_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_OVERLAPPING_STREAM_DATA)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_UNENCRYPTED_STREAM_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_UNENCRYPTED_STREAM_DATA)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA:
-      return {true,
-              {static_cast<uint64_t>(
-                  QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_MAYBE_CORRUPTED_MEMORY:
-      return {true, {static_cast<uint64_t>(QUIC_MAYBE_CORRUPTED_MEMORY)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_UNENCRYPTED_FEC_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_UNENCRYPTED_FEC_DATA)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_INVALID_RST_STREAM_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_RST_STREAM_DATA)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_CONNECTION_CLOSE_DATA:
-      return {true,
-              {static_cast<uint64_t>(QUIC_INVALID_CONNECTION_CLOSE_DATA)}};
+      return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}};
     case QUIC_INVALID_GOAWAY_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_GOAWAY_DATA)}};
+      return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}};
     case QUIC_INVALID_WINDOW_UPDATE_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_WINDOW_UPDATE_DATA)}};
+      return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}};
     case QUIC_INVALID_BLOCKED_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_BLOCKED_DATA)}};
+      return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}};
     case QUIC_INVALID_STOP_WAITING_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_STOP_WAITING_DATA)}};
+      return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}};
     case QUIC_INVALID_PATH_CLOSE_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_PATH_CLOSE_DATA)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_INVALID_ACK_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_ACK_DATA)}};
+      return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}};
     case QUIC_INVALID_MESSAGE_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_MESSAGE_DATA)}};
+      return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}};
     case QUIC_INVALID_VERSION_NEGOTIATION_PACKET:
-      return {true,
-              {static_cast<uint64_t>(QUIC_INVALID_VERSION_NEGOTIATION_PACKET)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_PUBLIC_RST_PACKET:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_PUBLIC_RST_PACKET)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_DECRYPTION_FAILURE:
-      return {true, {static_cast<uint64_t>(QUIC_DECRYPTION_FAILURE)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_ENCRYPTION_FAILURE:
-      return {true, {static_cast<uint64_t>(QUIC_ENCRYPTION_FAILURE)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_PACKET_TOO_LARGE:
-      return {true, {static_cast<uint64_t>(QUIC_PACKET_TOO_LARGE)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_PEER_GOING_AWAY:
-      return {true, {static_cast<uint64_t>(QUIC_PEER_GOING_AWAY)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_INVALID_STREAM_ID:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_STREAM_ID)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_PRIORITY:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_PRIORITY)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_TOO_MANY_OPEN_STREAMS:
-      return {true, {static_cast<uint64_t>(QUIC_TOO_MANY_OPEN_STREAMS)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_TOO_MANY_AVAILABLE_STREAMS:
-      return {true, {static_cast<uint64_t>(QUIC_TOO_MANY_AVAILABLE_STREAMS)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_PUBLIC_RESET:
-      return {true, {static_cast<uint64_t>(QUIC_PUBLIC_RESET)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_INVALID_VERSION:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_VERSION)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_HEADER_ID:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_HEADER_ID)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_INVALID_NEGOTIATED_VALUE:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_NEGOTIATED_VALUE)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_DECOMPRESSION_FAILURE:
-      return {true, {static_cast<uint64_t>(QUIC_DECOMPRESSION_FAILURE)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_NETWORK_IDLE_TIMEOUT:
-      return {true, {static_cast<uint64_t>(QUIC_NETWORK_IDLE_TIMEOUT)}};
+      return {true, {static_cast<uint64_t>(NO_IETF_QUIC_ERROR)}};
     case QUIC_HANDSHAKE_TIMEOUT:
-      return {true, {static_cast<uint64_t>(QUIC_HANDSHAKE_TIMEOUT)}};
+      return {true, {static_cast<uint64_t>(NO_IETF_QUIC_ERROR)}};
     case QUIC_ERROR_MIGRATING_ADDRESS:
-      return {true, {static_cast<uint64_t>(QUIC_ERROR_MIGRATING_ADDRESS)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_ERROR_MIGRATING_PORT:
-      return {true, {static_cast<uint64_t>(QUIC_ERROR_MIGRATING_PORT)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_PACKET_WRITE_ERROR:
-      return {true, {static_cast<uint64_t>(QUIC_PACKET_WRITE_ERROR)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_PACKET_READ_ERROR:
-      return {true, {static_cast<uint64_t>(QUIC_PACKET_READ_ERROR)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_EMPTY_STREAM_FRAME_NO_FIN:
-      return {true, {static_cast<uint64_t>(QUIC_EMPTY_STREAM_FRAME_NO_FIN)}};
+      return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}};
     case QUIC_INVALID_HEADERS_STREAM_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_HEADERS_STREAM_DATA)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE:
-      return {
-          true,
-          {static_cast<uint64_t>(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA:
-      return {
-          true,
-          {static_cast<uint64_t>(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)}};
+      return {true, {static_cast<uint64_t>(FLOW_CONTROL_ERROR)}};
     case QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA:
-      return {true,
-              {static_cast<uint64_t>(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_FLOW_CONTROL_INVALID_WINDOW:
-      return {true, {static_cast<uint64_t>(QUIC_FLOW_CONTROL_INVALID_WINDOW)}};
+      return {true, {static_cast<uint64_t>(FLOW_CONTROL_ERROR)}};
     case QUIC_CONNECTION_IP_POOLED:
-      return {true, {static_cast<uint64_t>(QUIC_CONNECTION_IP_POOLED)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS:
-      return {true,
-              {static_cast<uint64_t>(QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS:
-      return {
-          true,
-          {static_cast<uint64_t>(QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_CONNECTION_CANCELLED:
-      return {true, {static_cast<uint64_t>(QUIC_CONNECTION_CANCELLED)}};
+      return {true, {static_cast<uint64_t>(NO_IETF_QUIC_ERROR)}};
     case QUIC_BAD_PACKET_LOSS_RATE:
-      return {true, {static_cast<uint64_t>(QUIC_BAD_PACKET_LOSS_RATE)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_PUBLIC_RESETS_POST_HANDSHAKE:
-      return {true, {static_cast<uint64_t>(QUIC_PUBLIC_RESETS_POST_HANDSHAKE)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_FAILED_TO_SERIALIZE_PACKET:
-      return {true, {static_cast<uint64_t>(QUIC_FAILED_TO_SERIALIZE_PACKET)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_TOO_MANY_RTOS:
-      return {true, {static_cast<uint64_t>(QUIC_TOO_MANY_RTOS)}};
+      return {true, {static_cast<uint64_t>(NO_IETF_QUIC_ERROR)}};
     case QUIC_HANDSHAKE_FAILED:
-      return {true, {static_cast<uint64_t>(QUIC_HANDSHAKE_FAILED)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_TAGS_OUT_OF_ORDER:
-      return {true, {static_cast<uint64_t>(QUIC_CRYPTO_TAGS_OUT_OF_ORDER)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_TOO_MANY_ENTRIES:
-      return {true, {static_cast<uint64_t>(QUIC_CRYPTO_TOO_MANY_ENTRIES)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_INVALID_VALUE_LENGTH:
-      return {true, {static_cast<uint64_t>(QUIC_CRYPTO_INVALID_VALUE_LENGTH)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE:
-      return {true,
-              {static_cast<uint64_t>(
-                  QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_CRYPTO_MESSAGE_TYPE:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_CRYPTO_MESSAGE_TYPE)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER:
-      return {true,
-              {static_cast<uint64_t>(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_CHANNEL_ID_SIGNATURE:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_CHANNEL_ID_SIGNATURE)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
-      return {true,
-              {static_cast<uint64_t>(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP:
-      return {
-          true,
-          {static_cast<uint64_t>(QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND:
-      return {true,
-              {static_cast<uint64_t>(QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_UNSUPPORTED_PROOF_DEMAND:
-      return {true, {static_cast<uint64_t>(QUIC_UNSUPPORTED_PROOF_DEMAND)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_INTERNAL_ERROR:
-      return {true, {static_cast<uint64_t>(QUIC_CRYPTO_INTERNAL_ERROR)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_CRYPTO_VERSION_NOT_SUPPORTED:
-      return {true, {static_cast<uint64_t>(QUIC_CRYPTO_VERSION_NOT_SUPPORTED)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_NO_SUPPORT:
-      return {true, {static_cast<uint64_t>(QUIC_CRYPTO_NO_SUPPORT)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_TOO_MANY_REJECTS:
-      return {true, {static_cast<uint64_t>(QUIC_CRYPTO_TOO_MANY_REJECTS)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_PROOF_INVALID:
-      return {true, {static_cast<uint64_t>(QUIC_PROOF_INVALID)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_DUPLICATE_TAG:
-      return {true, {static_cast<uint64_t>(QUIC_CRYPTO_DUPLICATE_TAG)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT:
-      return {true,
-              {static_cast<uint64_t>(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_SERVER_CONFIG_EXPIRED:
-      return {true, {static_cast<uint64_t>(QUIC_CRYPTO_SERVER_CONFIG_EXPIRED)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED:
-      return {true,
-              {static_cast<uint64_t>(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO:
-      return {true,
-              {static_cast<uint64_t>(
-                  QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE:
-      return {true,
-              {static_cast<uint64_t>(
-                  QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_CRYPTO_CHLO_TOO_LARGE:
-      return {true, {static_cast<uint64_t>(QUIC_CRYPTO_CHLO_TOO_LARGE)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_VERSION_NEGOTIATION_MISMATCH:
-      return {true, {static_cast<uint64_t>(QUIC_VERSION_NEGOTIATION_MISMATCH)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_BAD_MULTIPATH_FLAG:
-      return {true, {static_cast<uint64_t>(QUIC_BAD_MULTIPATH_FLAG)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_MULTIPATH_PATH_DOES_NOT_EXIST:
-      return {true,
-              {static_cast<uint64_t>(QUIC_MULTIPATH_PATH_DOES_NOT_EXIST)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_MULTIPATH_PATH_NOT_ACTIVE:
-      return {true, {static_cast<uint64_t>(QUIC_MULTIPATH_PATH_NOT_ACTIVE)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_IP_ADDRESS_CHANGED:
-      return {true, {static_cast<uint64_t>(QUIC_IP_ADDRESS_CHANGED)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS:
-      return {true,
-              {static_cast<uint64_t>(
-                  QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES:
-      return {
-          true,
-          {static_cast<uint64_t>(QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK:
-      return {
-          true,
-          {static_cast<uint64_t>(QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM:
-      return {true,
-              {static_cast<uint64_t>(
-                  QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG:
-      return {true,
-              {static_cast<uint64_t>(
-                  QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR:
-      return {
-          true,
-          {static_cast<uint64_t>(QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED:
-      return {true,
-              {static_cast<uint64_t>(
-                  QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_TOO_MANY_STREAM_DATA_INTERVALS:
-      return {true,
-              {static_cast<uint64_t>(QUIC_TOO_MANY_STREAM_DATA_INTERVALS)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_STREAM_SEQUENCER_INVALID_STATE:
-      return {true,
-              {static_cast<uint64_t>(QUIC_STREAM_SEQUENCER_INVALID_STATE)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_TOO_MANY_SESSIONS_ON_SERVER:
-      return {true, {static_cast<uint64_t>(QUIC_TOO_MANY_SESSIONS_ON_SERVER)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_STREAM_LENGTH_OVERFLOW:
-      return {true, {static_cast<uint64_t>(QUIC_STREAM_LENGTH_OVERFLOW)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_MAX_DATA_FRAME_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_MAX_DATA_FRAME_DATA)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA:
-      return {true,
-              {static_cast<uint64_t>(QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_MAX_STREAMS_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_MAX_STREAMS_DATA)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_STREAMS_BLOCKED_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_STREAMS_BLOCKED_DATA)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_STREAM_BLOCKED_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_STREAM_BLOCKED_DATA)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_NEW_CONNECTION_ID_DATA:
-      return {true,
-              {static_cast<uint64_t>(QUIC_INVALID_NEW_CONNECTION_ID_DATA)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_STOP_SENDING_FRAME_DATA:
-      return {true,
-              {static_cast<uint64_t>(QUIC_INVALID_STOP_SENDING_FRAME_DATA)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_PATH_CHALLENGE_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_PATH_CHALLENGE_DATA)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_PATH_RESPONSE_DATA:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_PATH_RESPONSE_DATA)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case IETF_QUIC_PROTOCOL_VIOLATION:
-      return {true, {static_cast<uint64_t>(IETF_QUIC_PROTOCOL_VIOLATION)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_INVALID_NEW_TOKEN:
-      return {true, {static_cast<uint64_t>(QUIC_INVALID_NEW_TOKEN)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM:
-      return {true,
-              {static_cast<uint64_t>(
-                  QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM)}};
+      return {true, {static_cast<uint64_t>(STREAM_STATE_ERROR)}};
     case QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM:
-      return {true,
-              {static_cast<uint64_t>(
-                  QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_INVALID_RETIRE_CONNECTION_ID_DATA:
-      return {true,
-              {static_cast<uint64_t>(QUIC_INVALID_RETIRE_CONNECTION_ID_DATA)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_STREAMS_BLOCKED_ERROR:
-      return {true, {static_cast<uint64_t>(QUIC_STREAMS_BLOCKED_ERROR)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_MAX_STREAMS_ERROR:
-      return {true, {static_cast<uint64_t>(QUIC_MAX_STREAMS_ERROR)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_HTTP_DECODER_ERROR:
-      return {true, {static_cast<uint64_t>(QUIC_HTTP_DECODER_ERROR)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_STALE_CONNECTION_CANCELLED:
-      return {true, {static_cast<uint64_t>(QUIC_STALE_CONNECTION_CANCELLED)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_IETF_GQUIC_ERROR_MISSING:
-      return {true, {static_cast<uint64_t>(QUIC_IETF_GQUIC_ERROR_MISSING)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM:
-      return {true,
-              {static_cast<uint64_t>(
-                  QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES:
-      return {true,
-              {static_cast<uint64_t>(QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_TRANSPORT_INVALID_CLIENT_INDICATION:
-      return {false, {0u}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_QPACK_DECOMPRESSION_FAILED:
       return {
           false,
@@ -442,10 +383,9 @@
           false,
           {static_cast<uint64_t>(IETF_QUIC_HTTP_QPACK_DECODER_STREAM_ERROR)}};
     case QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET:
-      return {true,
-              {static_cast<uint64_t>(QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_STREAM_MULTIPLE_OFFSET:
-      return {true, {static_cast<uint64_t>(QUIC_STREAM_MULTIPLE_OFFSET)}};
+      return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}};
     case QUIC_HTTP_FRAME_TOO_LARGE:
       return {false,
               {static_cast<uint64_t>(
@@ -493,50 +433,37 @@
               {static_cast<uint64_t>(
                   QuicHttp3ErrorCode::IETF_QUIC_HTTP3_SETTINGS_ERROR)}};
     case QUIC_HPACK_INDEX_VARINT_ERROR:
-      return {false, {static_cast<uint64_t>(QUIC_HPACK_INDEX_VARINT_ERROR)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_NAME_LENGTH_VARINT_ERROR:
-      return {false,
-              {static_cast<uint64_t>(QUIC_HPACK_NAME_LENGTH_VARINT_ERROR)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR:
-      return {false,
-              {static_cast<uint64_t>(QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_NAME_TOO_LONG:
-      return {false, {static_cast<uint64_t>(QUIC_HPACK_NAME_TOO_LONG)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_VALUE_TOO_LONG:
-      return {false, {static_cast<uint64_t>(QUIC_HPACK_VALUE_TOO_LONG)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_NAME_HUFFMAN_ERROR:
-      return {false, {static_cast<uint64_t>(QUIC_HPACK_NAME_HUFFMAN_ERROR)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_VALUE_HUFFMAN_ERROR:
-      return {false, {static_cast<uint64_t>(QUIC_HPACK_VALUE_HUFFMAN_ERROR)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
-      return {false,
-              {static_cast<uint64_t>(
-                  QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_INVALID_INDEX:
-      return {false, {static_cast<uint64_t>(QUIC_HPACK_INVALID_INDEX)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_INVALID_NAME_INDEX:
-      return {false, {static_cast<uint64_t>(QUIC_HPACK_INVALID_NAME_INDEX)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
-      return {false,
-              {static_cast<uint64_t>(
-                  QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
-      return {
-          false,
-          {static_cast<uint64_t>(
-              QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
-      return {false,
-              {static_cast<uint64_t>(
-                  QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_TRUNCATED_BLOCK:
-      return {false, {static_cast<uint64_t>(QUIC_HPACK_TRUNCATED_BLOCK)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_FRAGMENT_TOO_LONG:
-      return {false, {static_cast<uint64_t>(QUIC_HPACK_FRAGMENT_TOO_LONG)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
-      return {false,
-              {static_cast<uint64_t>(
-                  QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT)}};
+      return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}};
     case QUIC_LAST_ERROR:
       return {false, {static_cast<uint64_t>(QUIC_LAST_ERROR)}};
   }
diff --git a/quic/core/quic_types.h b/quic/core/quic_types.h
index 76d3bab..9e801cd 100644
--- a/quic/core/quic_types.h
+++ b/quic/core/quic_types.h
@@ -584,6 +584,8 @@
   };
 };
 
+// Convert QuicErrorCode to transport or application IETF error code
+// to be used in CONNECTION_CLOSE frames.
 QUIC_EXPORT_PRIVATE QuicErrorCodeToIetfMapping
 QuicErrorCodeToTransportErrorCode(QuicErrorCode error);
 
diff --git a/quic/core/quic_types_test.cc b/quic/core/quic_types_test.cc
index dc37c43..485c3b6 100644
--- a/quic/core/quic_types_test.cc
+++ b/quic/core/quic_types_test.cc
@@ -56,6 +56,36 @@
                 static_cast<quic::QuicIetfTransportErrorCodes>(0x400)));
 }
 
+TEST_F(QuicTypesTest, QuicErrorCodeToTransportErrorCode) {
+  for (int internal_error_code = 0; internal_error_code < QUIC_LAST_ERROR;
+       ++internal_error_code) {
+    std::string internal_error_code_string =
+        QuicErrorCodeToString(static_cast<QuicErrorCode>(internal_error_code));
+    if (internal_error_code_string == "INVALID_ERROR_CODE") {
+      // Not a valid QuicErrorCode.
+      continue;
+    }
+    QuicErrorCodeToIetfMapping ietf_error_code =
+        QuicErrorCodeToTransportErrorCode(
+            static_cast<QuicErrorCode>(internal_error_code));
+    if (ietf_error_code.is_transport_close_) {
+      QuicIetfTransportErrorCodes transport_error_code =
+          ietf_error_code.transport_error_code_;
+      bool is_valid_transport_error_code = transport_error_code <= 0x0d;
+      EXPECT_TRUE(is_valid_transport_error_code) << internal_error_code_string;
+    } else {
+      // Non-transport errors are application errors, either HTTP/3 or QPACK.
+      uint64_t application_error_code = ietf_error_code.application_error_code_;
+      bool is_valid_http3_error_code =
+          application_error_code >= 0x100 && application_error_code <= 0x110;
+      bool is_valid_qpack_error_code =
+          application_error_code >= 0x200 && application_error_code <= 0x202;
+      EXPECT_TRUE(is_valid_http3_error_code || is_valid_qpack_error_code)
+          << internal_error_code_string;
+    }
+  }
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace quic