Deprecate quic_ignore_key_update_not_yet_supported

Context: before this implementation supported IETF QUIC key updates, we introduced a custom "key_update_not_yet_supported" transport parameter that was sent to indicate this version of the code did not support key updates. When we implemented key updates, we stopped sending the transport parameter, but would disable them if we received the transport parameter.  This CL deprecates gfe2_reloadable_flag_quic_ignore_key_update_not_yet_supported which means that we now no longer act on receiving the transport parameter at all. Now that this transport parameter is no longer sent or parsed, it can be fully removed, along with all the machinery to negotiate key updates.

Note that CL was originally reviewed at cl/425663257 and was rolled back via cl/426198777. We are now rolling this forward since we have fixed the Chrome merge issues via https://crrev.com/c/3451177. This CL does not have any changes from cl/425663257.

PiperOrigin-RevId: 427765515
diff --git a/quic/core/crypto/transport_parameters.cc b/quic/core/crypto/transport_parameters.cc
index b1f3cd5..0d828db 100644
--- a/quic/core/crypto/transport_parameters.cc
+++ b/quic/core/crypto/transport_parameters.cc
@@ -56,7 +56,7 @@
   kGoogleConnectionOptions = 0x3128,
   // 0x3129 was used to convey the user agent string.
   // 0x312A was used only in T050 to indicate support for HANDSHAKE_DONE.
-  kGoogleKeyUpdateNotYetSupported = 0x312B,
+  // 0x312B was used to indicate that QUIC+TLS key updates were not supported.
   // 0x4751 was used for non-standard Google-specific parameters encoded as a
   // Google QUIC_CRYPTO CHLO, it has been replaced by individual parameters.
   kGoogleQuicVersion =
@@ -122,8 +122,6 @@
       return "initial_round_trip_time";
     case TransportParameters::kGoogleConnectionOptions:
       return "google_connection_options";
-    case TransportParameters::kGoogleKeyUpdateNotYetSupported:
-      return "key_update_not_yet_supported";
     case TransportParameters::kGoogleQuicVersion:
       return "google-version";
     case TransportParameters::kMinAckDelay:
@@ -162,8 +160,6 @@
       return true;
     case TransportParameters::kVersionInformation:
       return GetQuicReloadableFlag(quic_version_information);
-    case TransportParameters::kGoogleKeyUpdateNotYetSupported:
-      return !GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported);
   }
   return false;
 }
@@ -443,9 +439,6 @@
       rv += QuicTagToString(connection_option);
     }
   }
-  if (key_update_not_yet_supported) {
-    rv += " " + TransportParameterIdToString(kGoogleKeyUpdateNotYetSupported);
-  }
   for (const auto& kv : custom_parameters) {
     absl::StrAppend(&rv, " 0x", absl::Hex(static_cast<uint32_t>(kv.first)),
                     "=");
@@ -485,8 +478,7 @@
                                  kMinActiveConnectionIdLimitTransportParam,
                                  kVarInt62MaxValue),
       max_datagram_frame_size(kMaxDatagramFrameSize),
-      initial_round_trip_time_us(kInitialRoundTripTime),
-      key_update_not_yet_supported(false)
+      initial_round_trip_time_us(kInitialRoundTripTime)
 // Important note: any new transport parameters must be added
 // to TransportParameters::AreValid, SerializeTransportParameters and
 // ParseTransportParameters, TransportParameters's custom copy constructor, the
@@ -520,7 +512,6 @@
       max_datagram_frame_size(other.max_datagram_frame_size),
       initial_round_trip_time_us(other.initial_round_trip_time_us),
       google_connection_options(other.google_connection_options),
-      key_update_not_yet_supported(other.key_update_not_yet_supported),
       custom_parameters(other.custom_parameters) {
   if (other.preferred_address) {
     preferred_address = std::make_unique<TransportParameters::PreferredAddress>(
@@ -561,7 +552,6 @@
         initial_round_trip_time_us.value() ==
             rhs.initial_round_trip_time_us.value() &&
         google_connection_options == rhs.google_connection_options &&
-        key_update_not_yet_supported == rhs.key_update_not_yet_supported &&
         custom_parameters == rhs.custom_parameters)) {
     return false;
   }
@@ -744,7 +734,6 @@
       kIntegerParameterLength +           // max_datagram_frame_size
       kIntegerParameterLength +           // initial_round_trip_time_us
       kTypeAndValueLength +               // google_connection_options
-      kTypeAndValueLength +               // key_update_not_yet_supported
       kTypeAndValueLength;                // google-version
 
   std::vector<TransportParameters::TransportParameterId> parameter_ids = {
@@ -769,7 +758,6 @@
       TransportParameters::kInitialSourceConnectionId,
       TransportParameters::kRetrySourceConnectionId,
       TransportParameters::kGoogleConnectionOptions,
-      TransportParameters::kGoogleKeyUpdateNotYetSupported,
       TransportParameters::kGoogleQuicVersion,
       TransportParameters::kVersionInformation,
   };
@@ -1104,18 +1092,6 @@
           }
         }
       } break;
-      // Google-specific indicator for key update not yet supported.
-      case TransportParameters::kGoogleKeyUpdateNotYetSupported: {
-        if (in.key_update_not_yet_supported) {
-          if (!writer.WriteVarInt62(
-                  TransportParameters::kGoogleKeyUpdateNotYetSupported) ||
-              !writer.WriteVarInt62(/* transport parameter length */ 0)) {
-            QUIC_BUG(Failed to write key_update_not_yet_supported)
-                << "Failed to write key_update_not_yet_supported for " << in;
-            return false;
-          }
-        }
-      } break;
       // Google-specific version extension.
       case TransportParameters::kGoogleQuicVersion: {
         if (!in.legacy_version_information.has_value()) {
@@ -1438,31 +1414,6 @@
           out->google_connection_options.value().push_back(connection_option);
         }
       } break;
-      case TransportParameters::kGoogleKeyUpdateNotYetSupported:
-        if (GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) {
-          QUIC_RELOADABLE_FLAG_COUNT_N(quic_ignore_key_update_not_yet_supported,
-                                       1, 2);
-          QUIC_CODE_COUNT(quic_ignore_key_update_not_yet_supported_ignored);
-          // This is a copy of the default switch statement below.
-          // TODO(dschinazi) remove this case entirely when deprecating the
-          // quic_ignore_key_update_not_yet_supported flag.
-          if (out->custom_parameters.find(param_id) !=
-              out->custom_parameters.end()) {
-            *error_details = "Received a second unknown parameter" +
-                             TransportParameterIdToString(param_id);
-            return false;
-          }
-          out->custom_parameters[param_id] =
-              std::string(value_reader.ReadRemainingPayload());
-          break;
-        }
-        QUIC_CODE_COUNT(quic_ignore_key_update_not_yet_supported_received);
-        if (out->key_update_not_yet_supported) {
-          *error_details = "Received a second key_update_not_yet_supported";
-          return false;
-        }
-        out->key_update_not_yet_supported = true;
-        break;
       case TransportParameters::kGoogleQuicVersion: {
         if (!out->legacy_version_information.has_value()) {
           out->legacy_version_information =
diff --git a/quic/core/crypto/transport_parameters.h b/quic/core/crypto/transport_parameters.h
index 4c4874b..1b6f516 100644
--- a/quic/core/crypto/transport_parameters.h
+++ b/quic/core/crypto/transport_parameters.h
@@ -260,10 +260,6 @@
   // Google-specific connection options.
   absl::optional<QuicTagVector> google_connection_options;
 
-  // Google-specific mechanism to indicate that IETF QUIC Key Update has not
-  // yet been implemented. This will be removed once we implement it.
-  bool key_update_not_yet_supported;
-
   // Validates whether transport parameters are valid according to
   // the specification. If the transport parameters are not valid, this method
   // will write a human-readable error message to |error_details|.
diff --git a/quic/core/crypto/transport_parameters_test.cc b/quic/core/crypto/transport_parameters_test.cc
index dcf747c..c9df18a 100644
--- a/quic/core/crypto/transport_parameters_test.cc
+++ b/quic/core/crypto/transport_parameters_test.cc
@@ -37,7 +37,6 @@
 const uint8_t kFakePreferredStatelessResetTokenData[16] = {
     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
     0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F};
-const bool kFakeKeyUpdateNotYetSupported = true;
 
 const auto kCustomParameter1 =
     static_cast<TransportParameters::TransportParameterId>(0xffcd);
@@ -287,7 +286,6 @@
   orig_params.retry_source_connection_id = CreateFakeRetrySourceConnectionId();
   orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
   orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
-  orig_params.key_update_not_yet_supported = kFakeKeyUpdateNotYetSupported;
   orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
   orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
 
@@ -324,9 +322,6 @@
       CreateFakeInitialSourceConnectionId();
   orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
   orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
-  if (!GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) {
-    orig_params.key_update_not_yet_supported = kFakeKeyUpdateNotYetSupported;
-  }
   orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
   orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
 
@@ -570,9 +565,6 @@
       'A', 'L', 'P', 'N',  // value
       'E', 'F', 'G', 0x00,
       'H', 'I', 'J', 0xff,
-      // key_update_not_yet_supported
-      0x71, 0x2B,  // parameter id
-      0x00,  // length
       // Google version extension
       0x80, 0x00, 0x47, 0x52,  // parameter id
       0x04,  // length
@@ -637,9 +629,6 @@
   ASSERT_TRUE(new_params.google_connection_options.has_value());
   EXPECT_EQ(CreateFakeGoogleConnectionOptions(),
             new_params.google_connection_options.value());
-  if (!GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) {
-    EXPECT_TRUE(new_params.key_update_not_yet_supported);
-  }
 }
 
 TEST_P(TransportParametersTest,
@@ -826,9 +815,6 @@
       'A', 'L', 'P', 'N',  // value
       'E', 'F', 'G', 0x00,
       'H', 'I', 'J', 0xff,
-      // key_update_not_yet_supported
-      0x71, 0x2B,  // parameter id
-      0x00,  // length
       // Google version extension
       0x80, 0x00, 0x47, 0x52,  // parameter id
       0x0d,  // length
@@ -915,9 +901,6 @@
   ASSERT_TRUE(new_params.google_connection_options.has_value());
   EXPECT_EQ(CreateFakeGoogleConnectionOptions(),
             new_params.google_connection_options.value());
-  if (!GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) {
-    EXPECT_TRUE(new_params.key_update_not_yet_supported);
-  }
 }
 
 TEST_P(TransportParametersTest, ParseServerParametersRepeated) {
@@ -1035,7 +1018,6 @@
       CreateFakeInitialSourceConnectionId();
   orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
   orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
-  orig_params.key_update_not_yet_supported = kFakeKeyUpdateNotYetSupported;
   orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
   orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
 
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index 5db1aab..4550621 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -153,7 +153,6 @@
   }
   void SetServerApplicationStateForResumption(
       std::unique_ptr<ApplicationState> /*application_state*/) override {}
-  bool KeyUpdateSupportedLocally() const override { return false; }
   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
       override {
     return nullptr;
diff --git a/quic/core/http/quic_spdy_stream_test.cc b/quic/core/http/quic_spdy_stream_test.cc
index 3bbb271..c8146e1 100644
--- a/quic/core/http/quic_spdy_stream_test.cc
+++ b/quic/core/http/quic_spdy_stream_test.cc
@@ -136,7 +136,6 @@
   }
   void SetServerApplicationStateForResumption(
       std::unique_ptr<ApplicationState> /*application_state*/) override {}
-  bool KeyUpdateSupportedLocally() const override { return true; }
   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
       override {
     return nullptr;
diff --git a/quic/core/quic_config.cc b/quic/core/quic_config.cc
index 796c641..8313ef7 100644
--- a/quic/core/quic_config.cc
+++ b/quic/core/quic_config.cc
@@ -456,8 +456,6 @@
       initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL),
       initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL),
       connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL),
-      key_update_supported_remotely_(false),
-      key_update_supported_locally_(false),
       alternate_server_address_ipv6_(kASAD, PRESENCE_OPTIONAL),
       alternate_server_address_ipv4_(kASAD, PRESENCE_OPTIONAL),
       stateless_reset_token_(kSRST, PRESENCE_OPTIONAL),
@@ -863,22 +861,6 @@
   return connection_migration_disabled_.HasReceivedValue();
 }
 
-void QuicConfig::SetKeyUpdateSupportedLocally() {
-  key_update_supported_locally_ = true;
-}
-
-bool QuicConfig::KeyUpdateSupportedForConnection() const {
-  return KeyUpdateSupportedRemotely() && KeyUpdateSupportedLocally();
-}
-
-bool QuicConfig::KeyUpdateSupportedLocally() const {
-  return key_update_supported_locally_;
-}
-
-bool QuicConfig::KeyUpdateSupportedRemotely() const {
-  return key_update_supported_remotely_;
-}
-
 void QuicConfig::SetIPv6AlternateServerAddressToSend(
     const QuicSocketAddress& alternate_server_address_ipv6) {
   if (!alternate_server_address_ipv6.host().IsIPv6()) {
@@ -1297,10 +1279,6 @@
     params->google_connection_options = connection_options_.GetSendValues();
   }
 
-  if (!KeyUpdateSupportedLocally()) {
-    params->key_update_not_yet_supported = true;
-  }
-
   params->custom_parameters = custom_transport_parameters_to_send_;
 
   return true;
@@ -1410,9 +1388,6 @@
   if (params.disable_active_migration) {
     connection_migration_disabled_.SetReceivedValue(1u);
   }
-  if (!is_resumption && !params.key_update_not_yet_supported) {
-    key_update_supported_remotely_ = true;
-  }
 
   active_connection_id_limit_.SetReceivedValue(
       params.active_connection_id_limit.value());
diff --git a/quic/core/quic_config.h b/quic/core/quic_config.h
index cb681c2..cb8b4ec 100644
--- a/quic/core/quic_config.h
+++ b/quic/core/quic_config.h
@@ -384,12 +384,6 @@
   void SetDisableConnectionMigration();
   bool DisableConnectionMigration() const;
 
-  // Key update support.
-  void SetKeyUpdateSupportedLocally();
-  bool KeyUpdateSupportedForConnection() const;
-  bool KeyUpdateSupportedLocally() const;
-  bool KeyUpdateSupportedRemotely() const;
-
   // IPv6 alternate server address.
   void SetIPv6AlternateServerAddressToSend(
       const QuicSocketAddress& alternate_server_address_ipv6);
@@ -593,13 +587,6 @@
   // Uses the disable_active_migration transport parameter in IETF QUIC.
   QuicFixedUint32 connection_migration_disabled_;
 
-  // Whether key update is supported by the peer. Uses key_update_not_yet
-  // supported transport parameter in IETF QUIC.
-  bool key_update_supported_remotely_;
-
-  // Whether key update is supported locally.
-  bool key_update_supported_locally_;
-
   // Alternate server addresses the client could connect to.
   // Uses the preferred_address transport parameter in IETF QUIC.
   // Note that when QUIC_CRYPTO is in use, only one of the addresses is sent.
diff --git a/quic/core/quic_config_test.cc b/quic/core/quic_config_test.cc
index 5124a97..e53d429 100644
--- a/quic/core/quic_config_test.cc
+++ b/quic/core/quic_config_test.cc
@@ -56,9 +56,6 @@
   EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
   EXPECT_EQ(kMaxIncomingPacketSize, config_.GetMaxPacketSizeToSend());
   EXPECT_FALSE(config_.HasReceivedMaxPacketSize());
-  EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
-  EXPECT_FALSE(config_.KeyUpdateSupportedLocally());
-  EXPECT_FALSE(config_.KeyUpdateSupportedRemotely());
 }
 
 TEST_P(QuicConfigTest, AutoSetIetfFlowControl) {
@@ -519,7 +516,6 @@
   EXPECT_EQ(
       static_cast<uint64_t>(kDefaultMinAckDelayTimeMs) * kNumMicrosPerMilli,
       params.min_ack_delay_us.value());
-  EXPECT_TRUE(params.key_update_not_yet_supported);
 
   EXPECT_EQ(params.preferred_address->ipv4_socket_address, kTestServerAddress);
   EXPECT_EQ(*reinterpret_cast<StatelessResetToken*>(
@@ -685,83 +681,6 @@
   EXPECT_TRUE(config_.DisableConnectionMigration());
 }
 
-TEST_P(QuicConfigTest, KeyUpdateNotYetSupportedTransportParameterNorLocally) {
-  if (!version_.UsesTls()) {
-    // TransportParameters are only used for QUIC+TLS.
-    return;
-  }
-  EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
-  EXPECT_FALSE(config_.KeyUpdateSupportedLocally());
-  EXPECT_FALSE(config_.KeyUpdateSupportedRemotely());
-  TransportParameters params;
-  params.key_update_not_yet_supported = true;
-  std::string error_details;
-  EXPECT_THAT(config_.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
-  EXPECT_FALSE(config_.KeyUpdateSupportedLocally());
-  EXPECT_FALSE(config_.KeyUpdateSupportedRemotely());
-}
-
-TEST_P(QuicConfigTest, KeyUpdateNotYetSupportedTransportParameter) {
-  if (!version_.UsesTls()) {
-    // TransportParameters are only used for QUIC+TLS.
-    return;
-  }
-  config_.SetKeyUpdateSupportedLocally();
-  EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
-  EXPECT_TRUE(config_.KeyUpdateSupportedLocally());
-
-  TransportParameters params;
-  params.key_update_not_yet_supported = true;
-  std::string error_details;
-  EXPECT_THAT(config_.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
-  EXPECT_TRUE(config_.KeyUpdateSupportedLocally());
-}
-
-TEST_P(QuicConfigTest, KeyUpdateSupportedRemotelyButNotLocally) {
-  if (!version_.UsesTls()) {
-    // TransportParameters are only used for QUIC+TLS.
-    return;
-  }
-  EXPECT_FALSE(config_.KeyUpdateSupportedLocally());
-  EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
-
-  TransportParameters params;
-  params.key_update_not_yet_supported = false;
-  std::string error_details;
-  EXPECT_THAT(config_.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
-  EXPECT_FALSE(config_.KeyUpdateSupportedLocally());
-  EXPECT_TRUE(config_.KeyUpdateSupportedRemotely());
-}
-
-TEST_P(QuicConfigTest, KeyUpdateSupported) {
-  if (!version_.UsesTls()) {
-    // TransportParameters are only used for QUIC+TLS.
-    return;
-  }
-  config_.SetKeyUpdateSupportedLocally();
-  EXPECT_TRUE(config_.KeyUpdateSupportedLocally());
-  EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
-
-  TransportParameters params;
-  params.key_update_not_yet_supported = false;
-  std::string error_details;
-  EXPECT_THAT(config_.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  EXPECT_TRUE(config_.KeyUpdateSupportedForConnection());
-  EXPECT_TRUE(config_.KeyUpdateSupportedLocally());
-  EXPECT_TRUE(config_.KeyUpdateSupportedRemotely());
-}
-
 TEST_P(QuicConfigTest, SendPreferredIPv4Address) {
   if (!version_.UsesTls()) {
     // TransportParameters are only used for QUIC+TLS.
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 1c1a4ea..974e192 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -505,8 +505,7 @@
     if (!ValidateConfigConnectionIds(config)) {
       return;
     }
-    support_key_update_for_connection_ =
-        config.KeyUpdateSupportedForConnection();
+    support_key_update_for_connection_ = version().UsesTls();
     framer_.SetKeyUpdateSupportForConnection(
         support_key_update_for_connection_);
   } else {
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 053849f..0969070 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -12758,13 +12758,11 @@
   }
 
   TransportParameters params;
-  params.key_update_not_yet_supported = false;
   QuicConfig config;
   std::string error_details;
   EXPECT_THAT(config.ProcessTransportParameters(
                   params, /* is_resumption = */ false, &error_details),
               IsQuicNoError());
-  config.SetKeyUpdateSupportedLocally();
   QuicConfigPeer::SetNegotiated(&config, true);
   if (connection_.version().UsesTls()) {
     QuicConfigPeer::SetReceivedOriginalConnectionId(
@@ -12920,12 +12918,10 @@
   std::string error_details;
   TransportParameters params;
   // Key update is enabled.
-  params.key_update_not_yet_supported = false;
   QuicConfig config;
   EXPECT_THAT(config.ProcessTransportParameters(
                   params, /* is_resumption = */ false, &error_details),
               IsQuicNoError());
-  config.SetKeyUpdateSupportedLocally();
   QuicConfigPeer::SetNegotiated(&config, true);
   if (connection_.version().UsesTls()) {
     QuicConfigPeer::SetReceivedOriginalConnectionId(
@@ -13018,12 +13014,10 @@
   std::string error_details;
   TransportParameters params;
   // Key update is enabled.
-  params.key_update_not_yet_supported = false;
   QuicConfig config;
   EXPECT_THAT(config.ProcessTransportParameters(
                   params, /* is_resumption = */ false, &error_details),
               IsQuicNoError());
-  config.SetKeyUpdateSupportedLocally();
   QuicConfigPeer::SetNegotiated(&config, true);
   if (connection_.version().UsesTls()) {
     QuicConfigPeer::SetReceivedOriginalConnectionId(
@@ -13059,137 +13053,6 @@
   TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
 }
 
-TEST_P(QuicConnectionTest,
-       CloseConnectionOnConfidentialityLimitKeyUpdateNotSupportedByPeer) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-
-  // Set key update confidentiality limit to 1 packet.
-  SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 1U);
-  // Use confidentiality limit for connection close of 3 packets.
-  constexpr size_t kConfidentialityLimit = 3U;
-
-  std::string error_details;
-  TransportParameters params;
-  // Key update not enabled for this connection as peer doesn't support it.
-  params.key_update_not_yet_supported = true;
-  QuicConfig config;
-  EXPECT_THAT(config.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  // Key update is supported locally.
-  config.SetKeyUpdateSupportedLocally();
-  QuicConfigPeer::SetNegotiated(&config, true);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  connection_.SetEncrypter(
-      ENCRYPTION_FORWARD_SECURE,
-      std::make_unique<NullEncrypterWithConfidentialityLimit>(
-          Perspective::IS_CLIENT, kConfidentialityLimit));
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  connection_.OnHandshakeComplete();
-
-  QuicPacketNumber last_packet;
-  // Send 3 packets and receive acks for them. Since key update is not enabled
-  // the confidentiality limit should be reached, forcing the connection to be
-  // closed.
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_TRUE(connection_.connected());
-  // Receive ack for packet.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame1 = InitAckFrame(1);
-  ProcessAckPacket(&frame1);
-
-  SendStreamDataToPeer(2, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_TRUE(connection_.connected());
-  // Receive ack for packet.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame2 = InitAckFrame(2);
-  ProcessAckPacket(&frame2);
-
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_FALSE(connection_.connected());
-  const QuicConnectionStats& stats = connection_.GetStats();
-  EXPECT_EQ(0U, stats.key_update_count);
-  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
-TEST_P(QuicConnectionTest,
-       CloseConnectionOnConfidentialityLimitKeyUpdateNotEnabledLocally) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-
-  // Set key update confidentiality limit to 1 packet.
-  SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 1U);
-  // Use confidentiality limit for connection close of 3 packets.
-  constexpr size_t kConfidentialityLimit = 3U;
-
-  std::string error_details;
-  TransportParameters params;
-  // Key update is supported by peer but not locally
-  // (config.SetKeyUpdateSupportedLocally is not called.)
-  params.key_update_not_yet_supported = false;
-  QuicConfig config;
-  EXPECT_THAT(config.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  QuicConfigPeer::SetNegotiated(&config, true);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  connection_.SetEncrypter(
-      ENCRYPTION_FORWARD_SECURE,
-      std::make_unique<NullEncrypterWithConfidentialityLimit>(
-          Perspective::IS_CLIENT, kConfidentialityLimit));
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  connection_.OnHandshakeComplete();
-
-  QuicPacketNumber last_packet;
-  // Send 3 packets and receive acks for them. Since key update is not enabled
-  // the confidentiality limit should be reached, forcing the connection to be
-  // closed.
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_TRUE(connection_.connected());
-  // Receive ack for packet.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame1 = InitAckFrame(1);
-  ProcessAckPacket(&frame1);
-
-  SendStreamDataToPeer(2, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_TRUE(connection_.connected());
-  // Receive ack for packet.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame2 = InitAckFrame(2);
-  ProcessAckPacket(&frame2);
-
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_FALSE(connection_.connected());
-  const QuicConnectionStats& stats = connection_.GetStats();
-  EXPECT_EQ(0U, stats.key_update_count);
-  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
 TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitDuringHandshake) {
   if (!connection_.version().UsesTls()) {
     return;
@@ -13345,13 +13208,11 @@
   constexpr QuicPacketCount kIntegrityLimit = 4;
 
   TransportParameters params;
-  params.key_update_not_yet_supported = false;
   QuicConfig config;
   std::string error_details;
   EXPECT_THAT(config.ProcessTransportParameters(
                   params, /* is_resumption = */ false, &error_details),
               IsQuicNoError());
-  config.SetKeyUpdateSupportedLocally();
   QuicConfigPeer::SetNegotiated(&config, true);
   if (connection_.version().UsesTls()) {
     QuicConfigPeer::SetReceivedOriginalConnectionId(
@@ -13796,12 +13657,10 @@
   // kept for key update, so enable key update for the test.
   std::string error_details;
   TransportParameters params;
-  params.key_update_not_yet_supported = false;
   QuicConfig config;
   EXPECT_THAT(config.ProcessTransportParameters(
                   params, /* is_resumption = */ false, &error_details),
               IsQuicNoError());
-  config.SetKeyUpdateSupportedLocally();
   QuicConfigPeer::SetNegotiated(&config, true);
   QuicConfigPeer::SetReceivedOriginalConnectionId(&config,
                                                   connection_.connection_id());
diff --git a/quic/core/quic_crypto_client_handshaker.cc b/quic/core/quic_crypto_client_handshaker.cc
index e9a9916..872b050 100644
--- a/quic/core/quic_crypto_client_handshaker.cc
+++ b/quic/core/quic_crypto_client_handshaker.cc
@@ -180,10 +180,6 @@
   return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
 }
 
-bool QuicCryptoClientHandshaker::KeyUpdateSupportedLocally() const {
-  return false;
-}
-
 std::unique_ptr<QuicDecrypter>
 QuicCryptoClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
   // Key update is only defined in QUIC+TLS.
diff --git a/quic/core/quic_crypto_client_handshaker.h b/quic/core/quic_crypto_client_handshaker.h
index d9f1035..c0c94b9 100644
--- a/quic/core/quic_crypto_client_handshaker.h
+++ b/quic/core/quic_crypto_client_handshaker.h
@@ -51,7 +51,6 @@
   CryptoMessageParser* crypto_message_parser() override;
   HandshakeState GetHandshakeState() const override;
   size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
-  bool KeyUpdateSupportedLocally() const override;
   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
       override;
   std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
diff --git a/quic/core/quic_crypto_client_stream.cc b/quic/core/quic_crypto_client_stream.cc
index 31d96a3..27a2a46 100644
--- a/quic/core/quic_crypto_client_stream.cc
+++ b/quic/core/quic_crypto_client_stream.cc
@@ -114,10 +114,6 @@
   return handshaker_->BufferSizeLimitForLevel(level);
 }
 
-bool QuicCryptoClientStream::KeyUpdateSupportedLocally() const {
-  return handshaker_->KeyUpdateSupportedLocally();
-}
-
 std::unique_ptr<QuicDecrypter>
 QuicCryptoClientStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
   return handshaker_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
diff --git a/quic/core/quic_crypto_client_stream.h b/quic/core/quic_crypto_client_stream.h
index e37a570..34928b6 100644
--- a/quic/core/quic_crypto_client_stream.h
+++ b/quic/core/quic_crypto_client_stream.h
@@ -183,9 +183,6 @@
     // buffered at each encryption level.
     virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const = 0;
 
-    // Returns whether the implementation supports key update.
-    virtual bool KeyUpdateSupportedLocally() const = 0;
-
     // Called to generate a decrypter for the next key phase. Each call should
     // generate the key for phase n+1.
     virtual std::unique_ptr<QuicDecrypter>
@@ -283,7 +280,6 @@
   void SetServerApplicationStateForResumption(
       std::unique_ptr<ApplicationState> application_state) override;
   size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
-  bool KeyUpdateSupportedLocally() const override;
   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
       override;
   std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
diff --git a/quic/core/quic_crypto_server_stream.cc b/quic/core/quic_crypto_server_stream.cc
index 28bfe4a..55b7bf1 100644
--- a/quic/core/quic_crypto_server_stream.cc
+++ b/quic/core/quic_crypto_server_stream.cc
@@ -435,10 +435,6 @@
   return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
 }
 
-bool QuicCryptoServerStream::KeyUpdateSupportedLocally() const {
-  return false;
-}
-
 std::unique_ptr<QuicDecrypter>
 QuicCryptoServerStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
   // Key update is only defined in QUIC+TLS.
diff --git a/quic/core/quic_crypto_server_stream.h b/quic/core/quic_crypto_server_stream.h
index cf4f6e0..aca9e9a 100644
--- a/quic/core/quic_crypto_server_stream.h
+++ b/quic/core/quic_crypto_server_stream.h
@@ -66,7 +66,6 @@
   void SetServerApplicationStateForResumption(
       std::unique_ptr<ApplicationState> state) override;
   size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
-  bool KeyUpdateSupportedLocally() const override;
   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
       override;
   std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
diff --git a/quic/core/quic_crypto_stream.h b/quic/core/quic_crypto_stream.h
index 08cb189..8197a5f 100644
--- a/quic/core/quic_crypto_stream.h
+++ b/quic/core/quic_crypto_stream.h
@@ -149,9 +149,6 @@
   // encryption level |level|.
   virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
 
-  // Returns whether the implementation supports key update.
-  virtual bool KeyUpdateSupportedLocally() const = 0;
-
   // Called to generate a decrypter for the next key phase. Each call should
   // generate the key for phase n+1.
   virtual std::unique_ptr<QuicDecrypter>
diff --git a/quic/core/quic_crypto_stream_test.cc b/quic/core/quic_crypto_stream_test.cc
index 1c18c7b..2c9ec0d 100644
--- a/quic/core/quic_crypto_stream_test.cc
+++ b/quic/core/quic_crypto_stream_test.cc
@@ -80,7 +80,6 @@
   HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
   void SetServerApplicationStateForResumption(
       std::unique_ptr<ApplicationState> /*application_state*/) override {}
-  bool KeyUpdateSupportedLocally() const override { return false; }
   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
       override {
     return nullptr;
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index b692cf5..58fcb2f 100644
--- a/quic/core/quic_flags_list.h
+++ b/quic/core/quic_flags_list.h
@@ -123,8 +123,6 @@
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_match_ietf_reset_code, true)
 // When the flag is true, exit STARTUP after the same number of loss events as PROBE_UP.
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_startup_probe_up_loss_events, true)
-// When true, QUIC server will ignore received key_update_not_yet_supported transport parameter.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_ignore_key_update_not_yet_supported, true)
 // When true, QUIC will both send and validate the version_information transport parameter.
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_version_information, true)
 // When true, defaults to BBR congestion control instead of Cubic.
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index 14d549a..202bff4 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -147,10 +147,6 @@
     connection_->OnSuccessfulVersionNegotiation();
   }
 
-  if (GetMutableCryptoStream()->KeyUpdateSupportedLocally()) {
-    config_.SetKeyUpdateSupportedLocally();
-  }
-
   if (QuicVersionUsesCryptoFrames(transport_version())) {
     return;
   }
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc
index 8d5e477..256865d 100644
--- a/quic/core/quic_session_test.cc
+++ b/quic/core/quic_session_test.cc
@@ -159,7 +159,6 @@
   }
   void SetServerApplicationStateForResumption(
       std::unique_ptr<ApplicationState> /*application_state*/) override {}
-  MOCK_METHOD(bool, KeyUpdateSupportedLocally, (), (const, override));
   MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
               AdvanceKeysAndCreateCurrentOneRttDecrypter,
               (),
@@ -235,8 +234,6 @@
         writev_consumes_all_data_(false),
         uses_pending_streams_(false),
         num_incoming_streams_created_(0) {
-    EXPECT_CALL(*GetMutableCryptoStream(), KeyUpdateSupportedLocally())
-        .WillRepeatedly(Return(false));
     Initialize();
     this->connection()->SetEncrypter(
         ENCRYPTION_FORWARD_SECURE,
@@ -2294,20 +2291,6 @@
   ASSERT_TRUE(session_.connection()->can_receive_ack_frequency_frame());
 }
 
-TEST_P(QuicSessionTestClient, KeyUpdateNotSupportedLocally) {
-  EXPECT_CALL(*session_.GetMutableCryptoStream(), KeyUpdateSupportedLocally())
-      .WillOnce(Return(false));
-  session_.Initialize();
-  EXPECT_FALSE(session_.config()->KeyUpdateSupportedLocally());
-}
-
-TEST_P(QuicSessionTestClient, KeyUpdateSupportedLocally) {
-  EXPECT_CALL(*session_.GetMutableCryptoStream(), KeyUpdateSupportedLocally())
-      .WillOnce(Return(true));
-  session_.Initialize();
-  EXPECT_TRUE(session_.config()->KeyUpdateSupportedLocally());
-}
-
 TEST_P(QuicSessionTestClient, FailedToCreateStreamIfTooCloseToIdleTimeout) {
   connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   EXPECT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc
index 886edb7..3cd47ad 100644
--- a/quic/core/tls_client_handshaker.cc
+++ b/quic/core/tls_client_handshaker.cc
@@ -394,10 +394,6 @@
   return TlsHandshaker::BufferSizeLimitForLevel(level);
 }
 
-bool TlsClientHandshaker::KeyUpdateSupportedLocally() const {
-  return true;
-}
-
 std::unique_ptr<QuicDecrypter>
 TlsClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
   return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter();
diff --git a/quic/core/tls_client_handshaker.h b/quic/core/tls_client_handshaker.h
index 4543f9b..c7db0ed 100644
--- a/quic/core/tls_client_handshaker.h
+++ b/quic/core/tls_client_handshaker.h
@@ -61,7 +61,6 @@
   CryptoMessageParser* crypto_message_parser() override;
   HandshakeState GetHandshakeState() const override;
   size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
-  bool KeyUpdateSupportedLocally() const override;
   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
       override;
   std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc
index 5067bc1..a16e729 100644
--- a/quic/core/tls_server_handshaker.cc
+++ b/quic/core/tls_server_handshaker.cc
@@ -419,10 +419,6 @@
   return TlsHandshaker::BufferSizeLimitForLevel(level);
 }
 
-bool TlsServerHandshaker::KeyUpdateSupportedLocally() const {
-  return true;
-}
-
 std::unique_ptr<QuicDecrypter>
 TlsServerHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
   return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter();
@@ -483,24 +479,6 @@
   // Notify QuicConnectionDebugVisitor.
   session()->connection()->OnTransportParametersReceived(client_params);
 
-  if (GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_ignore_key_update_not_yet_supported, 2,
-                                 2);
-  } else {
-    // Chrome clients before 86.0.4233.0 did not send the
-    // key_update_not_yet_supported transport parameter, but they did send a
-    // Google-internal transport parameter with identifier 0x4751. We treat
-    // reception of 0x4751 as having received key_update_not_yet_supported to
-    // ensure we do not use key updates with those older clients.
-    // TODO(dschinazi) remove this workaround once all of our QUIC+TLS Finch
-    // experiments have a min_version greater than 86.0.4233.0.
-    if (client_params.custom_parameters.find(
-            static_cast<TransportParameters::TransportParameterId>(0x4751)) !=
-        client_params.custom_parameters.end()) {
-      client_params.key_update_not_yet_supported = true;
-    }
-  }
-
   if (client_params.legacy_version_information.has_value() &&
       CryptoUtils::ValidateClientHelloVersion(
           client_params.legacy_version_information.value().version,
diff --git a/quic/core/tls_server_handshaker.h b/quic/core/tls_server_handshaker.h
index 01cf19b..d2f37b0 100644
--- a/quic/core/tls_server_handshaker.h
+++ b/quic/core/tls_server_handshaker.h
@@ -80,7 +80,6 @@
   void SetServerApplicationStateForResumption(
       std::unique_ptr<ApplicationState> state) override;
   size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
-  bool KeyUpdateSupportedLocally() const override;
   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
       override;
   std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
diff --git a/quic/test_tools/quic_test_utils.h b/quic/test_tools/quic_test_utils.h
index 44e9ca2..d8d0979 100644
--- a/quic/test_tools/quic_test_utils.h
+++ b/quic/test_tools/quic_test_utils.h
@@ -848,7 +848,6 @@
   HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
   void SetServerApplicationStateForResumption(
       std::unique_ptr<ApplicationState> /*application_state*/) override {}
-  bool KeyUpdateSupportedLocally() const override { return false; }
   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
       override {
     return nullptr;