HttpServerProperties: Pass in NIK to broken service methods.

Previous CLs have added NetworkIsolationKey support to broken-
alternative-services-related HttpServerProperties methods,
but they were still being passed empty NetworkIsolationKeys
by consumers. This CL makes consumers pass in the correct NIK,
and adds tests for all callsites.

Bug: 969890
Change-Id: I5b3d7947bfe91f7fcc6a19bcf30c399dd8f49d8a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1782666
Reviewed-by: Zhongyi Shi <[email protected]>
Commit-Queue: Matt Menke <[email protected]>
Cr-Commit-Position: refs/heads/master@{#695275}
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 149fdf6..4290dc6 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -172,6 +172,7 @@
   net_log_ = net_log;
   request_ = request_info;
   url_ = request_->url;
+  network_isolation_key_ = request_->network_isolation_key;
 #if BUILDFLAG(ENABLE_REPORTING)
   // Store values for later use in NEL report generation.
   request_method_ = request_->method;
@@ -326,7 +327,7 @@
       auth_controllers_[target]->NeedsHTTP11()) {
     session_->http_server_properties()->SetHTTP11Required(
         HttpServerProperties::GetNormalizedSchemeHostPort(request_->url),
-        request_->network_isolation_key);
+        network_isolation_key_);
   }
 
   bool keep_alive = false;
@@ -1163,7 +1164,7 @@
     if (response_.ssl_info.is_valid() &&
         !IsCertStatusError(response_.ssl_info.cert_status)) {
       session_->http_stream_factory()->ProcessAlternativeServices(
-          session_, request_->network_isolation_key, response_.headers.get(),
+          session_, network_isolation_key_, response_.headers.get(),
           url::SchemeHostPort(request_->url));
     }
   }
@@ -1256,7 +1257,7 @@
       HistogramBrokenAlternateProtocolLocation(
           BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_NETWORK_TRANSACTION);
       session_->http_server_properties()->MarkAlternativeServiceBroken(
-          retried_alternative_service_);
+          retried_alternative_service_, network_isolation_key_);
     }
 
 #if BUILDFLAG(ENABLE_REPORTING)
@@ -1577,7 +1578,7 @@
       if (HasExceededMaxRetries())
         break;
       if (session_->http_server_properties()->IsAlternativeServiceBroken(
-              retried_alternative_service_)) {
+              retried_alternative_service_, network_isolation_key_)) {
         // If the alternative service was marked as broken while the request
         // was in flight, retry the request which will not use the broken
         // alternative service.
diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h
index 3fb09d2..c7dbfaa2 100644
--- a/net/http/http_network_transaction.h
+++ b/net/http/http_network_transaction.h
@@ -20,6 +20,7 @@
 #include "net/base/completion_repeating_callback.h"
 #include "net/base/net_error_details.h"
 #include "net/base/net_export.h"
+#include "net/base/network_isolation_key.h"
 #include "net/base/request_priority.h"
 #include "net/http/http_auth.h"
 #include "net/http/http_request_headers.h"
@@ -323,6 +324,10 @@
   RequestPriority priority_;
   HttpResponseInfo response_;
 
+  // Copied from |request_|, as it's needed after the response body has been
+  // read.
+  NetworkIsolationKey network_isolation_key_;
+
   // |proxy_info_| is the ProxyInfo used by the HttpStreamRequest.
   ProxyInfo proxy_info_;
 
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 34169b5..d394d417 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -12637,7 +12637,8 @@
       server, NetworkIsolationKey(), alternative_service, expiration,
       HttpNetworkSession::Params().quic_params.supported_versions);
   // Mark the QUIC alternative service as broken.
-  http_server_properties->MarkAlternativeServiceBroken(alternative_service);
+  http_server_properties->MarkAlternativeServiceBroken(alternative_service,
+                                                       NetworkIsolationKey());
 
   HttpRequestInfo request;
   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
@@ -12711,7 +12712,8 @@
       server, NetworkIsolationKey(), alternative_service_info_vector);
 
   // Mark one of the QUIC alternative service as broken.
-  http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
+  http_server_properties->MarkAlternativeServiceBroken(alternative_service1,
+                                                       NetworkIsolationKey());
   EXPECT_EQ(2u, http_server_properties
                     ->GetAlternativeServiceInfos(server, NetworkIsolationKey())
                     .size());
@@ -12791,8 +12793,8 @@
   ASSERT_EQ(1u, alternative_service_info_vector.size());
   EXPECT_EQ(alternative_service,
             alternative_service_info_vector[0].alternative_service());
-  EXPECT_TRUE(
-      http_server_properties->IsAlternativeServiceBroken(alternative_service));
+  EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
 }
 
 // Ensure that we are not allowed to redirect traffic via an alternate protocol
@@ -16526,8 +16528,8 @@
 
   // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
   // for alternative service.
-  EXPECT_TRUE(
-      http_server_properties->IsAlternativeServiceBroken(alternative_service));
+  EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
 
   // Since |alternative_service| is broken, a second transaction to server
   // should not start an alternate Job.  It should pool to existing connection
diff --git a/net/http/http_server_properties.cc b/net/http/http_server_properties.cc
index a6921f6..9dff090 100644
--- a/net/http/http_server_properties.cc
+++ b/net/http/http_server_properties.cc
@@ -340,12 +340,14 @@
     AlternativeService alternative_service(it->alternative_service());
     if (alternative_service.host.empty()) {
       alternative_service.host = canonical->second.host();
-      if (IsAlternativeServiceBroken(alternative_service)) {
+      if (IsAlternativeServiceBroken(alternative_service,
+                                     network_isolation_key)) {
         ++it;
         continue;
       }
       alternative_service.host = origin.host();
-    } else if (IsAlternativeServiceBroken(alternative_service)) {
+    } else if (IsAlternativeServiceBroken(alternative_service,
+                                          network_isolation_key)) {
       ++it;
       continue;
     }
@@ -530,10 +532,12 @@
 void HttpServerProperties::ConfirmAlternativeService(
     const AlternativeService& alternative_service,
     const net::NetworkIsolationKey& network_isolation_key) {
-  bool old_value = IsAlternativeServiceBroken(alternative_service);
+  bool old_value =
+      IsAlternativeServiceBroken(alternative_service, network_isolation_key);
   broken_alternative_services_.Confirm(BrokenAlternativeService(
       alternative_service, network_isolation_key, use_network_isolation_key_));
-  bool new_value = IsAlternativeServiceBroken(alternative_service);
+  bool new_value =
+      IsAlternativeServiceBroken(alternative_service, network_isolation_key);
 
   // For persisting, we only care about the value returned by
   // IsAlternativeServiceBroken. If that value changes, then call persist.
@@ -829,7 +833,8 @@
     if (alternative_service.host.empty()) {
       alternative_service.host = canonical_server.host();
     }
-    if (!IsAlternativeServiceBroken(alternative_service)) {
+    if (!IsAlternativeServiceBroken(alternative_service,
+                                    network_isolation_key)) {
       return it;
     }
   }
diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h
index 56eaa43..78aab4cf 100644
--- a/net/http/http_server_properties.h
+++ b/net/http/http_server_properties.h
@@ -301,44 +301,38 @@
   // |network_isolation_key|. |alternative_service.host| must not be empty.
   void MarkAlternativeServiceBroken(
       const AlternativeService& alternative_service,
-      const net::NetworkIsolationKey& network_isolation_key =
-          NetworkIsolationKey());
+      const net::NetworkIsolationKey& network_isolation_key);
 
   // Marks |alternative_service| as broken in the context of
   // |network_isolation_key| until the default network changes.
   // |alternative_service.host| must not be empty.
   void MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
       const AlternativeService& alternative_service,
-      const net::NetworkIsolationKey& network_isolation_key =
-          NetworkIsolationKey());
+      const net::NetworkIsolationKey& network_isolation_key);
 
   // Marks |alternative_service| as recently broken in the context of
   // |network_isolation_key|. |alternative_service.host| must not be empty.
   void MarkAlternativeServiceRecentlyBroken(
       const AlternativeService& alternative_service,
-      const net::NetworkIsolationKey& network_isolation_key =
-          NetworkIsolationKey());
+      const net::NetworkIsolationKey& network_isolation_key);
 
   // Returns true iff |alternative_service| is currently broken in the context
   // of |network_isolation_key|. |alternative_service.host| must not be empty.
   bool IsAlternativeServiceBroken(
       const AlternativeService& alternative_service,
-      const net::NetworkIsolationKey& network_isolation_key =
-          NetworkIsolationKey()) const;
+      const net::NetworkIsolationKey& network_isolation_key) const;
 
   // Returns true iff |alternative_service| was recently broken in the context
   // of |network_isolation_key|. |alternative_service.host| must not be empty.
   bool WasAlternativeServiceRecentlyBroken(
       const AlternativeService& alternative_service,
-      const net::NetworkIsolationKey& network_isolation_key =
-          NetworkIsolationKey());
+      const net::NetworkIsolationKey& network_isolation_key);
 
   // Confirms that |alternative_service| is working in the context of
   // |network_isolation_key|. |alternative_service.host| must not be empty.
   void ConfirmAlternativeService(
       const AlternativeService& alternative_service,
-      const net::NetworkIsolationKey& network_isolation_key =
-          NetworkIsolationKey());
+      const net::NetworkIsolationKey& network_isolation_key);
 
   // Called when the default network changes.
   // Clears all the alternative services that were marked broken until the
diff --git a/net/http/http_server_properties_manager_unittest.cc b/net/http/http_server_properties_manager_unittest.cc
index ae7ea4d2..061825f950 100644
--- a/net/http/http_server_properties_manager_unittest.cc
+++ b/net/http/http_server_properties_manager_unittest.cc
@@ -563,28 +563,30 @@
   http_server_props_->SetHttp2AlternativeService(
       spdy_server_mail, NetworkIsolationKey(), alternative_service,
       one_day_from_now_);
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 
   EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
 
-  http_server_props_->MarkAlternativeServiceBroken(alternative_service);
-  EXPECT_TRUE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  http_server_props_->MarkAlternativeServiceBroken(alternative_service,
+                                                   NetworkIsolationKey());
+  EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 
   // In addition to the pref update task, there's now a task to mark the
   // alternative service as no longer broken.
   EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
 
-  http_server_props_->ConfirmAlternativeService(alternative_service);
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  http_server_props_->ConfirmAlternativeService(alternative_service,
+                                                NetworkIsolationKey());
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 
   EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
 
@@ -593,10 +595,10 @@
   FastForwardUntilNoTasksRemain();
   EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
 
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 }
 
 // Check the case that prefs are loaded only after setting alternative service
@@ -712,29 +714,30 @@
   http_server_props_->SetHttp2AlternativeService(
       spdy_server_mail, NetworkIsolationKey(), alternative_service,
       one_day_from_now_);
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 
   EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
 
   http_server_props_->MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
-      alternative_service);
-  EXPECT_TRUE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+      alternative_service, NetworkIsolationKey());
+  EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 
   // In addition to the pref update task, there's now a task to mark the
   // alternative service as no longer broken.
   EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
 
-  http_server_props_->ConfirmAlternativeService(alternative_service);
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  http_server_props_->ConfirmAlternativeService(alternative_service,
+                                                NetworkIsolationKey());
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 
   EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
 
@@ -743,10 +746,10 @@
   FastForwardUntilNoTasksRemain();
   EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
 
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 }
 
 TEST_F(HttpServerPropertiesManagerTest,
@@ -763,29 +766,29 @@
   http_server_props_->SetHttp2AlternativeService(
       spdy_server_mail, NetworkIsolationKey(), alternative_service,
       one_day_from_now_);
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 
   EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
 
   http_server_props_->MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
-      alternative_service);
-  EXPECT_TRUE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+      alternative_service, NetworkIsolationKey());
+  EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 
   // In addition to the pref update task, there's now a task to mark the
   // alternative service as no longer broken.
   EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
 
   http_server_props_->OnDefaultNetworkChanged();
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 
   EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
 
@@ -794,10 +797,10 @@
   FastForwardUntilNoTasksRemain();
   EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
 
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 }
 
 TEST_F(HttpServerPropertiesManagerTest, OnDefaultNetworkChangedWithBrokenOnly) {
@@ -813,28 +816,29 @@
   http_server_props_->SetHttp2AlternativeService(
       spdy_server_mail, NetworkIsolationKey(), alternative_service,
       one_day_from_now_);
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_FALSE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 
   EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
 
-  http_server_props_->MarkAlternativeServiceBroken(alternative_service);
-  EXPECT_TRUE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  http_server_props_->MarkAlternativeServiceBroken(alternative_service,
+                                                   NetworkIsolationKey());
+  EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 
   // In addition to the pref update task, there's now a task to mark the
   // alternative service as no longer broken.
   EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
 
   http_server_props_->OnDefaultNetworkChanged();
-  EXPECT_TRUE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 
   EXPECT_EQ(2u, GetPendingMainThreadTaskCount());
 
@@ -843,10 +847,10 @@
   FastForwardUntilNoTasksRemain();
   EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
 
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(alternative_service));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      alternative_service, NetworkIsolationKey()));
   EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 }
 
 TEST_F(HttpServerPropertiesManagerTest, SupportsQuic) {
@@ -967,7 +971,8 @@
   http_server_props_->SetAlternativeServices(spdy_server, NetworkIsolationKey(),
                                              alt_svc_info_vector);
 
-  http_server_props_->MarkAlternativeServiceBroken(broken_alternative_service);
+  http_server_props_->MarkAlternativeServiceBroken(broken_alternative_service,
+                                                   NetworkIsolationKey());
   http_server_props_->SetSupportsSpdy(spdy_server, NetworkIsolationKey(), true);
   http_server_props_->SetSupportsQuic(true, actual_address);
   ServerNetworkStats stats;
@@ -984,7 +989,7 @@
   EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
 
   EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
-      broken_alternative_service));
+      broken_alternative_service, NetworkIsolationKey()));
   EXPECT_TRUE(http_server_props_->SupportsRequestPriority(
       spdy_server, NetworkIsolationKey()));
   EXPECT_TRUE(HasAlternativeService(spdy_server, NetworkIsolationKey()));
@@ -1012,7 +1017,7 @@
   EXPECT_TRUE(callback_invoked_);
 
   EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
-      broken_alternative_service));
+      broken_alternative_service, NetworkIsolationKey()));
   EXPECT_FALSE(http_server_props_->SupportsRequestPriority(
       spdy_server, NetworkIsolationKey()));
   EXPECT_FALSE(HasAlternativeService(spdy_server, NetworkIsolationKey()));
@@ -1120,9 +1125,10 @@
       server_mail, NetworkIsolationKey(), mail_alternative_service,
       expiration3);
 
-  http_server_props_->MarkAlternativeServiceBroken(www_alternative_service2);
+  http_server_props_->MarkAlternativeServiceBroken(www_alternative_service2,
+                                                   NetworkIsolationKey());
   http_server_props_->MarkAlternativeServiceRecentlyBroken(
-      mail_alternative_service);
+      mail_alternative_service, NetworkIsolationKey());
 
   // #3: Set SPDY server map
   http_server_props_->SetSupportsSpdy(server_www, NetworkIsolationKey(), false);
@@ -1328,7 +1334,8 @@
       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
           broken_alternative_service, time_one_day_later));
   // #1: MarkAlternativeServiceBroken().
-  http_server_props_->MarkAlternativeServiceBroken(broken_alternative_service);
+  http_server_props_->MarkAlternativeServiceBroken(broken_alternative_service,
+                                                   NetworkIsolationKey());
 
   const AlternativeService expired_alternative_service(
       kProtoHTTP2, "expired.example.com", 443);
@@ -1713,10 +1720,12 @@
   AlternativeService cached_recently_broken_service(kProtoQUIC,
                                                     "cached_rbroken", 443);
 
-  http_server_props_->MarkAlternativeServiceBroken(cached_broken_service);
-  http_server_props_->MarkAlternativeServiceBroken(cached_broken_service2);
+  http_server_props_->MarkAlternativeServiceBroken(cached_broken_service,
+                                                   NetworkIsolationKey());
+  http_server_props_->MarkAlternativeServiceBroken(cached_broken_service2,
+                                                   NetworkIsolationKey());
   http_server_props_->MarkAlternativeServiceRecentlyBroken(
-      cached_recently_broken_service);
+      cached_recently_broken_service, NetworkIsolationKey());
 
   EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
   // There should be a task to remove remove alt services from the cache of
@@ -1843,12 +1852,12 @@
   // Verify broken alternative services.
   //
   AlternativeService prefs_broken_service(kProtoHTTP2, "www.google.com", 1234);
-  EXPECT_TRUE(
-      http_server_props_->IsAlternativeServiceBroken(cached_broken_service));
-  EXPECT_TRUE(
-      http_server_props_->IsAlternativeServiceBroken(cached_broken_service2));
-  EXPECT_TRUE(
-      http_server_props_->IsAlternativeServiceBroken(prefs_broken_service));
+  EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
+      cached_broken_service, NetworkIsolationKey()));
+  EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
+      cached_broken_service2, NetworkIsolationKey()));
+  EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
+      prefs_broken_service, NetworkIsolationKey()));
 
   // Verify brokenness expiration times.
   // |cached_broken_service|'s expiration time should've been overwritten by the
@@ -1858,19 +1867,19 @@
   // now which comes from the prefs.
   FastForwardBy(base::TimeDelta::FromMinutes(5) -
                 HttpServerProperties::GetUpdatePrefsDelayForTesting());
-  EXPECT_TRUE(
-      http_server_props_->IsAlternativeServiceBroken(cached_broken_service));
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(cached_broken_service2));
-  EXPECT_TRUE(
-      http_server_props_->IsAlternativeServiceBroken(prefs_broken_service));
+  EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
+      cached_broken_service, NetworkIsolationKey()));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      cached_broken_service2, NetworkIsolationKey()));
+  EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
+      prefs_broken_service, NetworkIsolationKey()));
   FastForwardBy(base::TimeDelta::FromDays(1));
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(cached_broken_service));
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(cached_broken_service2));
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(prefs_broken_service));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      cached_broken_service, NetworkIsolationKey()));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      cached_broken_service2, NetworkIsolationKey()));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      prefs_broken_service, NetworkIsolationKey()));
 
   // Now that |prefs_broken_service|'s brokenness has expired, it should've
   // been removed from the alternative services info vectors of all servers.
@@ -1893,61 +1902,64 @@
   // broken.
 
   EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      prefs_broken_service));
+      prefs_broken_service, NetworkIsolationKey()));
   EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      cached_recently_broken_service));
+      cached_recently_broken_service, NetworkIsolationKey()));
   EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      cached_broken_service));
+      cached_broken_service, NetworkIsolationKey()));
   EXPECT_TRUE(http_server_props_->WasAlternativeServiceRecentlyBroken(
-      cached_broken_service2));
+      cached_broken_service2, NetworkIsolationKey()));
   // Make sure |prefs_broken_service| has the right expiration delay when marked
   // broken. Since |prefs_broken_service| had no broken_count specified in the
   // prefs, a broken_count value of 1 should have been assumed by
   // |http_server_props_|.
-  http_server_props_->MarkAlternativeServiceBroken(prefs_broken_service);
+  http_server_props_->MarkAlternativeServiceBroken(prefs_broken_service,
+                                                   NetworkIsolationKey());
   EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
   EXPECT_NE(0u, GetPendingMainThreadTaskCount());
   FastForwardBy(base::TimeDelta::FromMinutes(10) -
                 base::TimeDelta::FromInternalValue(1));
-  EXPECT_TRUE(
-      http_server_props_->IsAlternativeServiceBroken(prefs_broken_service));
+  EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
+      prefs_broken_service, NetworkIsolationKey()));
   FastForwardBy(base::TimeDelta::FromInternalValue(1));
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(prefs_broken_service));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      prefs_broken_service, NetworkIsolationKey()));
   // Make sure |cached_recently_broken_service| has the right expiration delay
   // when marked broken.
   http_server_props_->MarkAlternativeServiceBroken(
-      cached_recently_broken_service);
+      cached_recently_broken_service, NetworkIsolationKey());
   EXPECT_NE(0u, GetPendingMainThreadTaskCount());
   FastForwardBy(base::TimeDelta::FromMinutes(40) -
                 base::TimeDelta::FromInternalValue(1));
   EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
-      cached_recently_broken_service));
+      cached_recently_broken_service, NetworkIsolationKey()));
   FastForwardBy(base::TimeDelta::FromInternalValue(1));
   EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
-      cached_recently_broken_service));
+      cached_recently_broken_service, NetworkIsolationKey()));
   // Make sure |cached_broken_service| has the right expiration delay when
   // marked broken.
-  http_server_props_->MarkAlternativeServiceBroken(cached_broken_service);
+  http_server_props_->MarkAlternativeServiceBroken(cached_broken_service,
+                                                   NetworkIsolationKey());
   EXPECT_NE(0u, GetPendingMainThreadTaskCount());
   FastForwardBy(base::TimeDelta::FromMinutes(20) -
                 base::TimeDelta::FromInternalValue(1));
-  EXPECT_TRUE(
-      http_server_props_->IsAlternativeServiceBroken(cached_broken_service));
+  EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
+      cached_broken_service, NetworkIsolationKey()));
   FastForwardBy(base::TimeDelta::FromInternalValue(1));
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(cached_broken_service));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      cached_broken_service, NetworkIsolationKey()));
   // Make sure |cached_broken_service2| has the right expiration delay when
   // marked broken.
-  http_server_props_->MarkAlternativeServiceBroken(cached_broken_service2);
+  http_server_props_->MarkAlternativeServiceBroken(cached_broken_service2,
+                                                   NetworkIsolationKey());
   EXPECT_NE(0u, GetPendingMainThreadTaskCount());
   FastForwardBy(base::TimeDelta::FromMinutes(10) -
                 base::TimeDelta::FromInternalValue(1));
-  EXPECT_TRUE(
-      http_server_props_->IsAlternativeServiceBroken(cached_broken_service2));
+  EXPECT_TRUE(http_server_props_->IsAlternativeServiceBroken(
+      cached_broken_service2, NetworkIsolationKey()));
   FastForwardBy(base::TimeDelta::FromInternalValue(1));
-  EXPECT_FALSE(
-      http_server_props_->IsAlternativeServiceBroken(cached_broken_service2));
+  EXPECT_FALSE(http_server_props_->IsAlternativeServiceBroken(
+      cached_broken_service2, NetworkIsolationKey()));
 
   //
   // Verify ServerNetworkStats.
diff --git a/net/http/http_server_properties_unittest.cc b/net/http/http_server_properties_unittest.cc
index e42e51c..8b58814 100644
--- a/net/http/http_server_properties_unittest.cc
+++ b/net/http/http_server_properties_unittest.cc
@@ -772,14 +772,15 @@
   const AlternativeService alternative_service_with_foo_hostname(kProtoHTTP2,
                                                                  "foo", 1234);
   SetAlternativeService(server, alternative_service_with_empty_hostname);
-  impl_.MarkAlternativeServiceBroken(alternative_service_with_foo_hostname);
+  impl_.MarkAlternativeServiceBroken(alternative_service_with_foo_hostname,
+                                     NetworkIsolationKey());
 
   std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
       std::make_unique<HttpServerProperties::ServerInfoMap>();
   impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
 
-  EXPECT_TRUE(
-      impl_.IsAlternativeServiceBroken(alternative_service_with_foo_hostname));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(
+      alternative_service_with_foo_hostname, NetworkIsolationKey()));
   const AlternativeServiceInfoVector alternative_service_info_vector =
       impl_.GetAlternativeServiceInfos(server, NetworkIsolationKey());
   ASSERT_EQ(1u, alternative_service_info_vector.size());
@@ -939,16 +940,19 @@
   ASSERT_EQ(1u, alternative_service_info_vector.size());
   EXPECT_EQ(alternative_service1,
             alternative_service_info_vector[0].alternative_service());
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
+                                                NetworkIsolationKey()));
 
   // GetAlternativeServiceInfos should return the broken alternative service.
-  impl_.MarkAlternativeServiceBroken(alternative_service1);
+  impl_.MarkAlternativeServiceBroken(alternative_service1,
+                                     NetworkIsolationKey());
   alternative_service_info_vector =
       impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
   ASSERT_EQ(1u, alternative_service_info_vector.size());
   EXPECT_EQ(alternative_service1,
             alternative_service_info_vector[0].alternative_service());
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
+                                               NetworkIsolationKey()));
 
   // SetAlternativeServices should add a broken alternative service to the map.
   AlternativeServiceInfoVector alternative_service_info_vector2;
@@ -969,8 +973,10 @@
             alternative_service_info_vector[0].alternative_service());
   EXPECT_EQ(alternative_service2,
             alternative_service_info_vector[1].alternative_service());
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1));
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
+                                               NetworkIsolationKey()));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
+                                                NetworkIsolationKey()));
 
   // SetAlternativeService should add a broken alternative service to the map.
   SetAlternativeService(test_server, alternative_service1);
@@ -979,7 +985,8 @@
   ASSERT_EQ(1u, alternative_service_info_vector.size());
   EXPECT_EQ(alternative_service1,
             alternative_service_info_vector[0].alternative_service());
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
+                                               NetworkIsolationKey()));
 }
 
 TEST_F(AlternateProtocolServerPropertiesTest,
@@ -992,18 +999,20 @@
   ASSERT_EQ(1u, alternative_service_info_vector.size());
   EXPECT_EQ(alternative_service1,
             alternative_service_info_vector[0].alternative_service());
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
+                                                NetworkIsolationKey()));
 
   // Mark the alternative service as broken until the default network changes.
   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
-      alternative_service1);
+      alternative_service1, NetworkIsolationKey());
   // The alternative service should be persisted and marked as broken.
   alternative_service_info_vector =
       impl_.GetAlternativeServiceInfos(test_server, NetworkIsolationKey());
   ASSERT_EQ(1u, alternative_service_info_vector.size());
   EXPECT_EQ(alternative_service1,
             alternative_service_info_vector[0].alternative_service());
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
+                                               NetworkIsolationKey()));
 
   // SetAlternativeServices should add a broken alternative service to the map.
   AlternativeServiceInfoVector alternative_service_info_vector2;
@@ -1024,8 +1033,10 @@
             alternative_service_info_vector[0].alternative_service());
   EXPECT_EQ(alternative_service2,
             alternative_service_info_vector[1].alternative_service());
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1));
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
+                                               NetworkIsolationKey()));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
+                                                NetworkIsolationKey()));
 
   // SetAlternativeService should add a broken alternative service to the map.
   SetAlternativeService(test_server, alternative_service1);
@@ -1034,7 +1045,8 @@
   ASSERT_EQ(1u, alternative_service_info_vector.size());
   EXPECT_EQ(alternative_service1,
             alternative_service_info_vector[0].alternative_service());
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
+                                               NetworkIsolationKey()));
 }
 
 TEST_F(AlternateProtocolServerPropertiesTest, MaxAge) {
@@ -1203,8 +1215,10 @@
             alternative_service_info_vector[0].alternative_service());
 
   const AlternativeService broken_alternative_service(kProtoHTTP2, "foo", 443);
-  impl_.MarkAlternativeServiceBroken(broken_alternative_service);
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service));
+  impl_.MarkAlternativeServiceBroken(broken_alternative_service,
+                                     NetworkIsolationKey());
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service,
+                                               NetworkIsolationKey()));
 
   SetAlternativeService(test_server, broken_alternative_service);
   alternative_service_info_vector =
@@ -1212,21 +1226,25 @@
   ASSERT_EQ(1u, alternative_service_info_vector.size());
   EXPECT_EQ(broken_alternative_service,
             alternative_service_info_vector[0].alternative_service());
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service,
+                                               NetworkIsolationKey()));
 }
 
 TEST_F(AlternateProtocolServerPropertiesTest, ClearBroken) {
   url::SchemeHostPort test_server("http", "foo", 80);
   const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
   SetAlternativeService(test_server, alternative_service);
-  impl_.MarkAlternativeServiceBroken(alternative_service);
+  impl_.MarkAlternativeServiceBroken(alternative_service,
+                                     NetworkIsolationKey());
   ASSERT_TRUE(HasAlternativeService(test_server, NetworkIsolationKey()));
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                               NetworkIsolationKey()));
   // SetAlternativeServices should leave a broken alternative service marked
   // as such.
   impl_.SetAlternativeServices(test_server, NetworkIsolationKey(),
                                AlternativeServiceInfoVector());
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                               NetworkIsolationKey()));
 }
 
 TEST_F(AlternateProtocolServerPropertiesTest,
@@ -1343,16 +1361,23 @@
   const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
   SetAlternativeService(server, alternative_service);
 
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                                NetworkIsolationKey()));
+  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
+      alternative_service, NetworkIsolationKey()));
 
-  impl_.MarkAlternativeServiceRecentlyBroken(alternative_service);
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+  impl_.MarkAlternativeServiceRecentlyBroken(alternative_service,
+                                             NetworkIsolationKey());
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                                NetworkIsolationKey()));
+  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
+                                                        NetworkIsolationKey()));
 
-  impl_.ConfirmAlternativeService(alternative_service);
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+  impl_.ConfirmAlternativeService(alternative_service, NetworkIsolationKey());
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                                NetworkIsolationKey()));
+  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
+      alternative_service, NetworkIsolationKey()));
 }
 
 TEST_F(AlternateProtocolServerPropertiesTest,
@@ -1469,17 +1494,23 @@
   const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
   SetAlternativeService(server, alternative_service);
 
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                                NetworkIsolationKey()));
+  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
+      alternative_service, NetworkIsolationKey()));
 
   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
-      alternative_service);
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+      alternative_service, NetworkIsolationKey());
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                               NetworkIsolationKey()));
+  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
+                                                        NetworkIsolationKey()));
 
-  impl_.ConfirmAlternativeService(alternative_service);
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+  impl_.ConfirmAlternativeService(alternative_service, NetworkIsolationKey());
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                                NetworkIsolationKey()));
+  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
+      alternative_service, NetworkIsolationKey()));
 }
 
 TEST_F(AlternateProtocolServerPropertiesTest,
@@ -1597,45 +1628,62 @@
   const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
 
   SetAlternativeService(server, alternative_service);
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                                NetworkIsolationKey()));
+  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
+      alternative_service, NetworkIsolationKey()));
 
   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
-      alternative_service);
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+      alternative_service, NetworkIsolationKey());
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                               NetworkIsolationKey()));
+  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
+                                                        NetworkIsolationKey()));
 
   // Default network change clears alt svc broken until default network changes.
   impl_.OnDefaultNetworkChanged();
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                                NetworkIsolationKey()));
+  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
+      alternative_service, NetworkIsolationKey()));
 
   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
-      alternative_service);
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+      alternative_service, NetworkIsolationKey());
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                               NetworkIsolationKey()));
+  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
+                                                        NetworkIsolationKey()));
 
-  impl_.MarkAlternativeServiceBroken(alternative_service);
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+  impl_.MarkAlternativeServiceBroken(alternative_service,
+                                     NetworkIsolationKey());
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                               NetworkIsolationKey()));
+  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
+                                                        NetworkIsolationKey()));
 
   // Default network change doesn't affect alt svc that was simply marked broken
   // most recently.
   impl_.OnDefaultNetworkChanged();
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                               NetworkIsolationKey()));
+  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
+                                                        NetworkIsolationKey()));
 
   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
-      alternative_service);
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+      alternative_service, NetworkIsolationKey());
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                               NetworkIsolationKey()));
+  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
+                                                        NetworkIsolationKey()));
 
   // Default network change clears alt svc that was marked broken until default
   // network change most recently even if the alt svc was initially marked
   // broken.
   impl_.OnDefaultNetworkChanged();
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                                NetworkIsolationKey()));
+  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
+      alternative_service, NetworkIsolationKey()));
 }
 
 TEST_F(AlternateProtocolServerPropertiesTest,
@@ -1849,7 +1897,8 @@
 
   SetAlternativeService(canonical_server, canonical_alternative_service);
   EXPECT_TRUE(HasAlternativeService(test_server, NetworkIsolationKey()));
-  impl_.MarkAlternativeServiceBroken(canonical_alternative_service);
+  impl_.MarkAlternativeServiceBroken(canonical_alternative_service,
+                                     NetworkIsolationKey());
   EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
 }
 
@@ -1863,7 +1912,7 @@
   SetAlternativeService(canonical_server, canonical_alternative_service);
   EXPECT_TRUE(HasAlternativeService(test_server, NetworkIsolationKey()));
   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
-      canonical_alternative_service);
+      canonical_alternative_service, NetworkIsolationKey());
   EXPECT_FALSE(HasAlternativeService(test_server, NetworkIsolationKey()));
 }
 
@@ -1908,20 +1957,26 @@
   AlternativeService alternative_service(kProtoQUIC, "foo", 443);
   SetAlternativeService(server, alternative_service);
   EXPECT_TRUE(HasAlternativeService(server, NetworkIsolationKey()));
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                                NetworkIsolationKey()));
+  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
+      alternative_service, NetworkIsolationKey()));
 
   base::TimeTicks past =
       test_tick_clock_->NowTicks() - base::TimeDelta::FromSeconds(42);
   HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
       &impl_, alternative_service, past);
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                               NetworkIsolationKey()));
+  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
+                                                        NetworkIsolationKey()));
 
   HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
   EXPECT_FALSE(HasAlternativeService(server, NetworkIsolationKey()));
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service));
-  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
+                                                NetworkIsolationKey()));
+  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service,
+                                                        NetworkIsolationKey()));
 }
 
 TEST_F(AlternateProtocolServerPropertiesTest,
@@ -2043,10 +2098,10 @@
   // The alternative service of "bar:443" should be unaffected.
   EXPECT_TRUE(HasAlternativeService(bar_server2, NetworkIsolationKey()));
 
-  EXPECT_TRUE(
-      impl_.WasAlternativeServiceRecentlyBroken(bar_alternative_service));
-  EXPECT_FALSE(
-      impl_.WasAlternativeServiceRecentlyBroken(baz_alternative_service));
+  EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(bar_alternative_service,
+                                                        NetworkIsolationKey()));
+  EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
+      baz_alternative_service, NetworkIsolationKey()));
 }
 
 // Regression test for https://crbug.com/724302
@@ -2070,12 +2125,14 @@
   // Repeatedly mark alt svc 1 broken and wait for its brokenness to expire.
   // This will increase its time until expiration.
   for (int i = 0; i < 3; ++i) {
-    impl_.MarkAlternativeServiceBroken(alternative_service1);
+    impl_.MarkAlternativeServiceBroken(alternative_service1,
+                                       NetworkIsolationKey());
 
     // |impl_| should have posted task to expire the brokenness of
     // |alternative_service1|
     EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
-    EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1));
+    EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
+                                                 NetworkIsolationKey()));
 
     // Advance time by just enough so that |alternative_service1|'s brokenness
     // expires.
@@ -2083,27 +2140,35 @@
 
     // Ensure brokenness of |alternative_service1| has expired.
     EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
-    EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1));
+    EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
+                                                  NetworkIsolationKey()));
   }
 
-  impl_.MarkAlternativeServiceBroken(alternative_service1);
-  impl_.MarkAlternativeServiceBroken(alternative_service2);
+  impl_.MarkAlternativeServiceBroken(alternative_service1,
+                                     NetworkIsolationKey());
+  impl_.MarkAlternativeServiceBroken(alternative_service2,
+                                     NetworkIsolationKey());
 
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service2));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service2,
+                                               NetworkIsolationKey()));
 
   // Advance time by just enough so that |alternative_service2|'s brokennness
   // expires.
   FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[0]);
 
-  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1));
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2));
+  EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
+                                               NetworkIsolationKey()));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
+                                                NetworkIsolationKey()));
 
   // Advance time by enough so that |alternative_service1|'s brokenness expires.
   FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[3] -
                 BROKEN_ALT_SVC_EXPIRE_DELAYS[0]);
 
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1));
-  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
+                                                NetworkIsolationKey()));
+  EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
+                                                NetworkIsolationKey()));
 }
 
 // Regression test for https://crbug.com/994537. Having a ServerInfo entry
@@ -2169,11 +2234,11 @@
                                NetworkIsolationKey(),
                                alternative_service_info_vector);
 
-  impl_.MarkAlternativeServiceBroken(
-      AlternativeService(kProtoQUIC, "bar", 443));
+  impl_.MarkAlternativeServiceBroken(AlternativeService(kProtoQUIC, "bar", 443),
+                                     NetworkIsolationKey());
 
   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
-      AlternativeService(kProtoQUIC, "baz", 443));
+      AlternativeService(kProtoQUIC, "baz", 443), NetworkIsolationKey());
 
   alternative_service_info_vector.clear();
   alternative_service_info_vector.push_back(
diff --git a/net/http/http_stream_factory_job_controller.cc b/net/http/http_stream_factory_job_controller.cc
index 0d0665b..028e652 100644
--- a/net/http/http_stream_factory_job_controller.cc
+++ b/net/http/http_stream_factory_job_controller.cc
@@ -886,7 +886,8 @@
     // network changes.
     session_->http_server_properties()
         ->MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
-            alternative_service_info_.alternative_service());
+            alternative_service_info_.alternative_service(),
+            request_info_.network_isolation_key);
     // Reset error status for Jobs after reporting brokenness.
     ResetErrorStatusForJobs();
     return;
@@ -907,7 +908,8 @@
   HistogramBrokenAlternateProtocolLocation(
       BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_JOB_ALT);
   session_->http_server_properties()->MarkAlternativeServiceBroken(
-      alternative_service_info_.alternative_service());
+      alternative_service_info_.alternative_service(),
+      request_info_.network_isolation_key);
   // Reset error status for Jobs after reporting brokenness.
   ResetErrorStatusForJobs();
 }
@@ -1010,7 +1012,8 @@
     if (!quic_advertised && alternative_service_info.protocol() == kProtoQUIC)
       quic_advertised = true;
     const bool is_broken = http_server_properties.IsAlternativeServiceBroken(
-        alternative_service_info.alternative_service());
+        alternative_service_info.alternative_service(),
+        request_info.network_isolation_key);
     net_log_.AddEvent(
         NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_ALT_SVC_FOUND, [&] {
           return NetLogAltSvcParams(&alternative_service_info, is_broken);
diff --git a/net/http/http_stream_factory_job_controller_unittest.cc b/net/http/http_stream_factory_job_controller_unittest.cc
index 9d3c052..e03077f 100644
--- a/net/http/http_stream_factory_job_controller_unittest.cc
+++ b/net/http/http_stream_factory_job_controller_unittest.cc
@@ -303,7 +303,8 @@
     EXPECT_EQ(1u, alternative_service_info_vector.size());
     EXPECT_EQ(should_mark_broken,
               session_->http_server_properties()->IsAlternativeServiceBroken(
-                  alternative_service_info_vector[0].alternative_service()));
+                  alternative_service_info_vector[0].alternative_service(),
+                  NetworkIsolationKey()));
   }
 
   void TestAltJobSucceedsAfterMainJobFailed(
@@ -1891,7 +1892,7 @@
   // Now the alt service is marked as broken (e.g. through a different request),
   // so only non-alt job is restarted.
   session_->http_server_properties()->MarkAlternativeServiceBroken(
-      alternative_service);
+      alternative_service, NetworkIsolationKey());
 
   job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED,
                                   SSLConfig());
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index 6cc402d4..c435912 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -770,13 +770,15 @@
   }
 
   void AddQuicAlternateProtocolMapping(
-      MockCryptoClientStream::HandshakeMode handshake_mode) {
+      MockCryptoClientStream::HandshakeMode handshake_mode,
+      const NetworkIsolationKey& network_isolation_key =
+          NetworkIsolationKey()) {
     crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
     url::SchemeHostPort server(request_.url);
     AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
     base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
     http_server_properties_->SetQuicAlternativeService(
-        server, NetworkIsolationKey(), alternative_service, expiration,
+        server, network_isolation_key, alternative_service, expiration,
         supported_versions_);
   }
 
@@ -793,27 +795,33 @@
         supported_versions_);
   }
 
-  void ExpectBrokenAlternateProtocolMapping() {
+  void ExpectBrokenAlternateProtocolMapping(
+      const NetworkIsolationKey& network_isolation_key =
+          NetworkIsolationKey()) {
     const url::SchemeHostPort server(request_.url);
     const AlternativeServiceInfoVector alternative_service_info_vector =
         http_server_properties_->GetAlternativeServiceInfos(
-            server, NetworkIsolationKey());
+            server, network_isolation_key);
     EXPECT_EQ(1u, alternative_service_info_vector.size());
     EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
-        alternative_service_info_vector[0].alternative_service()));
+        alternative_service_info_vector[0].alternative_service(),
+        network_isolation_key));
   }
 
-  void ExpectQuicAlternateProtocolMapping() {
+  void ExpectQuicAlternateProtocolMapping(
+      const NetworkIsolationKey& network_isolation_key =
+          NetworkIsolationKey()) {
     const url::SchemeHostPort server(request_.url);
     const AlternativeServiceInfoVector alternative_service_info_vector =
         http_server_properties_->GetAlternativeServiceInfos(
-            server, NetworkIsolationKey());
+            server, network_isolation_key);
     EXPECT_EQ(1u, alternative_service_info_vector.size());
     EXPECT_EQ(
         kProtoQUIC,
         alternative_service_info_vector[0].alternative_service().protocol);
     EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
-        alternative_service_info_vector[0].alternative_service()));
+        alternative_service_info_vector[0].alternative_service(),
+        network_isolation_key));
   }
 
   void AddHangingNonAlternateProtocolSocketData() {
@@ -900,6 +908,67 @@
     SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
   }
 
+  // Adds a new socket data provider for an HTTP request, and runs a request,
+  // expecting it to be used.
+  void AddHttpDataAndRunRequest() {
+    MockWrite http_writes[] = {
+        MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
+        MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
+        MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
+
+    MockRead http_reads[] = {
+        MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
+        MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
+        MockRead(SYNCHRONOUS, 5, "http used"),
+        // Connection closed.
+        MockRead(SYNCHRONOUS, OK, 6)};
+    SequencedSocketData http_data(http_reads, http_writes);
+    socket_factory_.AddSocketDataProvider(&http_data);
+    SSLSocketDataProvider ssl_data(ASYNC, OK);
+    socket_factory_.AddSSLSocketDataProvider(&ssl_data);
+    SendRequestAndExpectHttpResponse("http used");
+    EXPECT_TRUE(http_data.AllWriteDataConsumed());
+    EXPECT_TRUE(http_data.AllReadDataConsumed());
+  }
+
+  // Adds a new socket data provider for a QUIC request, and runs a request,
+  // expecting it to be used. The new QUIC session is not closed.
+  void AddQuicDataAndRunRequest() {
+    QuicTestPacketMaker client_maker(
+        version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
+        &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
+        client_headers_include_h2_stream_dependency_);
+    QuicTestPacketMaker server_maker(
+        version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
+        &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
+    MockQuicData quic_data(version_);
+    client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
+    quic_data.AddWrite(
+        SYNCHRONOUS,
+        client_maker.MakeRequestHeadersPacket(
+            1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
+            ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
+            GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
+    client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
+    quic_data.AddRead(
+        ASYNC, server_maker.MakeResponseHeadersPacket(
+                   1, GetNthClientInitiatedBidirectionalStreamId(0), false,
+                   false, server_maker.GetResponseHeaders("200 OK"), nullptr));
+    std::string header = ConstructDataHeader(9);
+    quic_data.AddRead(
+        ASYNC, server_maker.MakeDataPacket(
+                   2, GetNthClientInitiatedBidirectionalStreamId(0), false,
+                   true, header + "quic used"));
+    // Don't care about the final ack.
+    quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
+    // No more data to read.
+    quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+    quic_data.AddSocketDataToFactory(&socket_factory_);
+    SendRequestAndExpectQuicResponse("quic used");
+
+    EXPECT_TRUE(quic_data.AllReadDataConsumed());
+  }
+
   quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
     return quic::test::GetNthClientInitiatedBidirectionalStreamId(
         version_.transport_version, n);
@@ -1918,8 +1987,12 @@
 TEST_P(QuicNetworkTransactionTest,
        UseAlternativeServiceForQuicWithNetworkIsolationKey) {
   base::test::ScopedFeatureList feature_list;
-  feature_list.InitAndEnableFeature(
-      features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
+  feature_list.InitWithFeatures(
+      // enabled_features
+      {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
+       features::kPartitionConnectionsByNetworkIsolationKey},
+      // disabled_features
+      {});
   // Since HttpServerProperties caches the feature value, have to create a new
   // one.
   http_server_properties_ = std::make_unique<HttpServerProperties>();
@@ -2695,6 +2768,149 @@
   ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
 }
 
+// Much like above test, but verifies NetworkIsolationKeys are respected.
+TEST_P(QuicNetworkTransactionTest,
+       RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
+  const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
+  const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
+  const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
+  const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
+
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      // enabled_features
+      {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
+       // Need to partition connections by NetworkIsolationKey for
+       // QuicSessionAliasKey to include NetworkIsolationKeys.
+       features::kPartitionConnectionsByNetworkIsolationKey},
+      // disabled_features
+      {});
+  // Since HttpServerProperties caches the feature value, have to create a new
+  // one.
+  http_server_properties_ = std::make_unique<HttpServerProperties>();
+
+  SetUpTestForRetryConnectionOnAlternateNetwork();
+
+  client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
+
+  // The request will initially go out over QUIC.
+  MockQuicData quic_data(version_);
+  quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);  // Hanging read
+  int packet_num = 1;
+  quic_data.AddWrite(SYNCHRONOUS,
+                     client_maker_.MakeDummyCHLOPacket(packet_num++));  // CHLO
+  // Retranmit the handshake messages.
+  quic_data.AddWrite(SYNCHRONOUS,
+                     client_maker_.MakeDummyCHLOPacket(packet_num++));
+  quic_data.AddWrite(SYNCHRONOUS,
+                     client_maker_.MakeDummyCHLOPacket(packet_num++));
+  quic_data.AddWrite(SYNCHRONOUS,
+                     client_maker_.MakeDummyCHLOPacket(packet_num++));
+  quic_data.AddWrite(SYNCHRONOUS,
+                     client_maker_.MakeDummyCHLOPacket(packet_num++));
+  // TODO(zhongyi): remove condition check once b/115926584 is fixed.
+  if (version_.transport_version <= quic::QUIC_VERSION_39) {
+    quic_data.AddWrite(SYNCHRONOUS,
+                       client_maker_.MakeDummyCHLOPacket(packet_num++));
+  }
+  // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
+  quic_data.AddWrite(SYNCHRONOUS,
+                     client_maker_.MakeConnectionClosePacket(
+                         packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
+                         "No recent network activity."));
+  quic_data.AddSocketDataToFactory(&socket_factory_);
+
+  // Add successful TCP data so that TCP job will succeed.
+  MockWrite http_writes[] = {
+      MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
+      MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
+      MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
+
+  MockRead http_reads[] = {
+      MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
+      MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
+      MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
+  SequencedSocketData http_data(http_reads, http_writes);
+  socket_factory_.AddSocketDataProvider(&http_data);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+  // Quic connection will be retried on the alternate network after the initial
+  // one fails on the default network.
+  MockQuicData quic_data2(version_);
+  quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);  // Handing read.
+  quic_data2.AddWrite(SYNCHRONOUS,
+                      client_maker_.MakeDummyCHLOPacket(1));  // CHLO
+
+  client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
+  if (VersionUsesQpack(version_.transport_version))
+    quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
+  quic_data2.AddSocketDataToFactory(&socket_factory_);
+
+  // Resolve the host resolution synchronously.
+  host_resolver_.set_synchronous_mode(true);
+  host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
+                                           "");
+
+  CreateSession();
+  session_->quic_stream_factory()->set_require_confirmation(true);
+  // Use a TestTaskRunner to avoid waiting in real time for timeouts.
+  QuicStreamFactoryPeer::SetAlarmFactory(
+      session_->quic_stream_factory(),
+      std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
+                                                 &clock_));
+  // Add alternate protocol mapping to race QUIC and TCP.
+  // QUIC connection requires handshake to be confirmed and sends CHLO to the
+  // peer.
+  AddQuicAlternateProtocolMapping(
+      MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
+  AddQuicAlternateProtocolMapping(
+      MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
+
+  request_.network_isolation_key = kNetworkIsolationKey1;
+  HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
+  TestCompletionCallback callback;
+  int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
+  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+
+  // Pump the message loop to get the request started.
+  // Request will be served with TCP job.
+  base::RunLoop().RunUntilIdle();
+  EXPECT_THAT(callback.WaitForResult(), IsOk());
+  CheckResponseData(&trans, "TCP succeeds");
+
+  // Fast forward to idle timeout the original connection. A new connection will
+  // be kicked off on the alternate network.
+  quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
+  ASSERT_TRUE(quic_data.AllReadDataConsumed());
+  ASSERT_TRUE(quic_data.AllWriteDataConsumed());
+
+  // The second connection hasn't finish handshake, verify that QUIC is not
+  // marked as broken.
+  ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
+  ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
+  // Explicitly confirm the handshake on the second connection.
+  crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
+      quic::QuicSession::HANDSHAKE_CONFIRMED);
+  // Run message loop to execute posted tasks, which will notify JoController
+  // about the orphaned job status.
+  base::RunLoop().RunUntilIdle();
+
+  // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
+  ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
+  ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
+
+  // Deliver a message to notify the new network becomes default, the previous
+  // brokenness will be clear as the brokenness is bond with old default
+  // network.
+  scoped_mock_change_notifier_->mock_network_change_notifier()
+      ->NotifyNetworkMadeDefault(kNewNetworkForTests);
+  ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
+  ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
+
+  ASSERT_TRUE(quic_data2.AllReadDataConsumed());
+  ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
+}
+
 // This test verifies that a new QUIC connection will be attempted on the
 // alternate network if the original QUIC connection fails with idle timeout
 // before handshake is confirmed. If TCP doesn't succeed but QUIC on the
@@ -3354,6 +3570,128 @@
   ASSERT_TRUE(http_data.AllReadDataConsumed());
 }
 
+// Much like above test, but verifies that NetworkIsolationKey is respected.
+TEST_P(QuicNetworkTransactionTest,
+       ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
+  const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
+  const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
+  const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
+  const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
+
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      // enabled_features
+      {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
+       features::kPartitionConnectionsByNetworkIsolationKey},
+      // disabled_features
+      {});
+  // Since HttpServerProperties caches the feature value, have to create a new
+  // one.
+  http_server_properties_ = std::make_unique<HttpServerProperties>();
+
+  session_params_.quic_params.idle_connection_timeout =
+      base::TimeDelta::FromSeconds(5);
+
+  // The request will initially go out over QUIC.
+  MockQuicData quic_data(version_);
+  client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
+  quic_data.AddWrite(SYNCHRONOUS,
+                     ConstructClientRequestHeadersPacket(
+                         1, GetNthClientInitiatedBidirectionalStreamId(0), true,
+                         true, GetRequestHeaders("GET", "https", "/")));
+  client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
+  uint64_t packet_number = 2;
+  quic_data.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
+
+  // Peer sending data from an non-existing stream causes this end to raise
+  // error and close connection.
+  quic_data.AddRead(
+      ASYNC, ConstructServerRstPacket(
+                 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
+                 quic::QUIC_STREAM_LAST_ERROR));
+  std::string quic_error_details = "Data for nonexistent stream";
+  quic_data.AddWrite(
+      SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
+                       packet_number++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
+                       quic::QUIC_INVALID_STREAM_ID, quic_error_details,
+                       quic::IETF_RST_STREAM));
+  quic_data.AddSocketDataToFactory(&socket_factory_);
+
+  // After that fails, it will be resent via TCP.
+  MockWrite http_writes[] = {
+      MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
+      MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
+      MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
+
+  MockRead http_reads[] = {
+      MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
+      MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
+      MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
+  SequencedSocketData http_data(http_reads, http_writes);
+  socket_factory_.AddSocketDataProvider(&http_data);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+  // In order for a new QUIC session to be established via alternate-protocol
+  // without racing an HTTP connection, we need the host resolution to happen
+  // synchronously.  Of course, even though QUIC *could* perform a 0-RTT
+  // connection to the the server, in this test we require confirmation
+  // before encrypting so the HTTP job will still start.
+  host_resolver_.set_synchronous_mode(true);
+  host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
+                                           "");
+
+  CreateSession();
+
+  AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
+                                  kNetworkIsolationKey1);
+  AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
+                                  kNetworkIsolationKey2);
+
+  HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
+  TestCompletionCallback callback;
+  request_.network_isolation_key = kNetworkIsolationKey1;
+  int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
+  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+
+  // Pump the message loop to get the request started.
+  base::RunLoop().RunUntilIdle();
+  // Explicitly confirm the handshake.
+  crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
+      quic::QuicSession::HANDSHAKE_CONFIRMED);
+  quic_data.Resume();
+
+  // Run the QUIC session to completion.
+  base::RunLoop().RunUntilIdle();
+  ASSERT_TRUE(quic_data.AllWriteDataConsumed());
+
+  // Let the transaction proceed which will result in QUIC being marked
+  // as broken and the request falling back to TCP.
+  EXPECT_THAT(callback.WaitForResult(), IsOk());
+  ASSERT_TRUE(quic_data.AllWriteDataConsumed());
+  ASSERT_FALSE(http_data.AllReadDataConsumed());
+
+  // Read the response body over TCP.
+  CheckResponseData(&trans, "hello world");
+  ASSERT_TRUE(http_data.AllWriteDataConsumed());
+  ASSERT_TRUE(http_data.AllReadDataConsumed());
+
+  // The alternative service shouldhave been marked as broken under
+  // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
+  ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
+  ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
+
+  // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
+  AddHttpDataAndRunRequest();
+  // Requests using other NetworkIsolationKeys can still use QUIC.
+  request_.network_isolation_key = kNetworkIsolationKey2;
+  AddQuicDataAndRunRequest();
+
+  // The last two requests should not have changed the alternative service
+  // mappings.
+  ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
+  ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
+}
+
 // Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
 // request is reset from, then QUIC will be marked as broken and the request
 // retried over TCP.
@@ -3509,14 +3847,15 @@
                                                   NetworkIsolationKey(),
                                                   alternative_services);
 
-  http_server_properties_->MarkAlternativeServiceBroken(local_alternative);
+  http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
+                                                        NetworkIsolationKey());
 
   SendRequestAndExpectQuicResponse("hello!");
 }
 
 // Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
 // request is reset from, then QUIC will be marked as broken and the request
-// retried over TCP. Then, subsequent requests will go over a new QUIC
+// retried over TCP. Then, subsequent requests will go over a new TCP
 // connection instead of going back to the broken QUIC connection.
 // This is a regression tests for crbug/731303.
 TEST_P(QuicNetworkTransactionTest,
@@ -3629,16 +3968,17 @@
 
   // Second request pools to existing connection with same destination,
   // because certificate matches, even though quic::QuicServerId is different.
-  // After it is reset, it will fail back to QUIC and mark QUIC as broken.
+  // After it is reset, it will fail back to TCP and mark QUIC as broken.
   request_.url = origin2;
   SendRequestAndExpectHttpResponse("hello world");
-  EXPECT_FALSE(
-      http_server_properties_->IsAlternativeServiceBroken(alternative1))
+  EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
+      alternative1, NetworkIsolationKey()))
       << alternative1.ToString();
-  EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(alternative2))
+  EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
+      alternative2, NetworkIsolationKey()))
       << alternative2.ToString();
 
-  // The third request should use a new QUIC connection, not the broken
+  // The third request should use a new TCP connection, not the broken
   // QUIC connection.
   SendRequestAndExpectHttpResponse("hello world");
 }
@@ -4222,9 +4562,9 @@
   AlternativeService alternative_service(kProtoQUIC,
                                          HostPortPair::FromURL(request_.url));
   http_server_properties_->MarkAlternativeServiceRecentlyBroken(
-      alternative_service);
+      alternative_service, NetworkIsolationKey());
   EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
 
   SendRequestAndExpectHttpResponse("hello world");
   SendRequestAndExpectQuicResponse("hello!");
@@ -4232,12 +4572,99 @@
   mock_quic_data.Resume();
 
   EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+      alternative_service, NetworkIsolationKey()));
   EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
                          url::SchemeHostPort("https", request_.url.host(), 443),
                          NetworkIsolationKey()));
 }
 
+TEST_P(QuicNetworkTransactionTest,
+       ConfirmAlternativeServiceWithNetworkIsolationKey) {
+  const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
+  const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
+  const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
+  const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
+
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      // enabled_features
+      {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
+       features::kPartitionConnectionsByNetworkIsolationKey},
+      // disabled_features
+      {});
+  // Since HttpServerProperties caches the feature value, have to create a new
+  // one.
+  http_server_properties_ = std::make_unique<HttpServerProperties>();
+
+  MockRead http_reads[] = {
+      MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
+      MockRead("hello world"),
+      MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+      MockRead(ASYNC, OK)};
+
+  StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
+  socket_factory_.AddSocketDataProvider(&http_data);
+  AddCertificate(&ssl_data_);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+  MockQuicData mock_quic_data(version_);
+  int packet_num = 1;
+  if (VersionUsesQpack(version_.transport_version)) {
+    mock_quic_data.AddWrite(SYNCHRONOUS,
+                            ConstructInitialSettingsPacket(packet_num++));
+  }
+  mock_quic_data.AddWrite(
+      SYNCHRONOUS,
+      ConstructClientRequestHeadersPacket(
+          packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
+          true, GetRequestHeaders("GET", "https", "/")));
+  mock_quic_data.AddRead(
+      ASYNC, ConstructServerResponseHeadersPacket(
+                 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
+                 GetResponseHeaders("200 OK")));
+  std::string header = ConstructDataHeader(6);
+  mock_quic_data.AddRead(
+      ASYNC, ConstructServerDataPacket(
+                 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
+                 header + "hello!"));
+  mock_quic_data.AddWrite(SYNCHRONOUS,
+                          ConstructClientAckPacket(packet_num++, 2, 1, 1));
+  mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);  // No more data to read
+  mock_quic_data.AddRead(ASYNC, 0);               // EOF
+
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+
+  CreateSession();
+
+  AlternativeService alternative_service(kProtoQUIC,
+                                         HostPortPair::FromURL(request_.url));
+  http_server_properties_->MarkAlternativeServiceRecentlyBroken(
+      alternative_service, kNetworkIsolationKey1);
+  http_server_properties_->MarkAlternativeServiceRecentlyBroken(
+      alternative_service, kNetworkIsolationKey2);
+  EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
+      alternative_service, kNetworkIsolationKey1));
+  EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
+      alternative_service, kNetworkIsolationKey2));
+
+  request_.network_isolation_key = kNetworkIsolationKey1;
+  SendRequestAndExpectHttpResponse("hello world");
+  SendRequestAndExpectQuicResponse("hello!");
+
+  mock_quic_data.Resume();
+
+  EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
+      alternative_service, kNetworkIsolationKey1));
+  EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
+                         url::SchemeHostPort("https", request_.url.host(), 443),
+                         kNetworkIsolationKey1));
+  EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
+      alternative_service, kNetworkIsolationKey2));
+  EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
+                         url::SchemeHostPort("https", request_.url.host(), 443),
+                         kNetworkIsolationKey2));
+}
+
 TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
   MockRead http_reads[] = {
       MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
@@ -4970,6 +5397,57 @@
   ExpectBrokenAlternateProtocolMapping();
 }
 
+TEST_P(QuicNetworkTransactionTest,
+       BrokenAlternateProtocolWithNetworkIsolationKey) {
+  const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
+  const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
+  const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
+  const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
+
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      // enabled_features
+      {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
+       features::kPartitionConnectionsByNetworkIsolationKey},
+      // disabled_features
+      {});
+  // Since HttpServerProperties caches the feature value, have to create a new
+  // one.
+  http_server_properties_ = std::make_unique<HttpServerProperties>();
+
+  // Alternate-protocol job
+  std::unique_ptr<quic::QuicEncryptedPacket> close(
+      ConstructServerConnectionClosePacket(1));
+  MockRead quic_reads[] = {
+      MockRead(ASYNC, close->data(), close->length()),
+      MockRead(ASYNC, ERR_IO_PENDING),  // No more data to read
+      MockRead(ASYNC, OK),              // EOF
+  };
+  StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
+  socket_factory_.AddSocketDataProvider(&quic_data);
+
+  // Main job which will succeed even though the alternate job fails.
+  MockRead http_reads[] = {
+      MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
+      MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+      MockRead(ASYNC, OK)};
+
+  StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
+  socket_factory_.AddSocketDataProvider(&http_data);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+  CreateSession();
+  AddQuicAlternateProtocolMapping(
+      MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
+  AddQuicAlternateProtocolMapping(
+      MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
+  request_.network_isolation_key = kNetworkIsolationKey1;
+  SendRequestAndExpectHttpResponse("hello from http");
+
+  ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
+  ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
+}
+
 TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
   // Alternate-protocol job
   MockRead quic_reads[] = {
@@ -5209,7 +5687,6 @@
   socket_factory_.AddSocketDataProvider(&http_data);
   socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
 
-  AddHangingNonAlternateProtocolSocketData();
   CreateSession();
 
   AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
@@ -5222,6 +5699,72 @@
   EXPECT_TRUE(quic_data.AllWriteDataConsumed());
 }
 
+TEST_P(QuicNetworkTransactionTest,
+       FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      // enabled_features
+      {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
+       features::kPartitionConnectionsByNetworkIsolationKey},
+      // disabled_features
+      {});
+  // Since HttpServerProperties caches the feature value, have to create a new
+  // one.
+  http_server_properties_ = std::make_unique<HttpServerProperties>();
+
+  const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
+  const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
+  const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
+  const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
+
+  // Alternate-protocol job
+  MockRead quic_reads[] = {
+      MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
+  };
+  StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
+  socket_factory_.AddSocketDataProvider(&quic_data);
+
+  // Second Alternate-protocol job which will race with the TCP job.
+  StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
+  socket_factory_.AddSocketDataProvider(&quic_data2);
+
+  // Final job that will proceed when the QUIC job fails.
+  MockRead http_reads[] = {
+      MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
+      MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+      MockRead(ASYNC, OK)};
+
+  StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
+  socket_factory_.AddSocketDataProvider(&http_data);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+  CreateSession();
+
+  AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
+                                  kNetworkIsolationKey1);
+  AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
+                                  kNetworkIsolationKey2);
+
+  request_.network_isolation_key = kNetworkIsolationKey1;
+  SendRequestAndExpectHttpResponse("hello from http");
+  EXPECT_TRUE(quic_data.AllReadDataConsumed());
+  EXPECT_TRUE(quic_data.AllWriteDataConsumed());
+
+  ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
+  ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
+
+  // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
+  AddHttpDataAndRunRequest();
+  // Requests using other NetworkIsolationKeys can still use QUIC.
+  request_.network_isolation_key = kNetworkIsolationKey2;
+  AddQuicDataAndRunRequest();
+
+  // The last two requests should not have changed the alternative service
+  // mappings.
+  ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
+  ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
+}
+
 TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
   // Alternate-protocol job
   MockRead quic_reads[] = {
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index adf37e73..96ee77d 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -1415,7 +1415,7 @@
   QuicSessionAliasKey key(destination, session_key);
   std::unique_ptr<Job> job =
       std::make_unique<Job>(this, quic_version, host_resolver_, key,
-                            WasQuicRecentlyBroken(session_key.server_id()),
+                            WasQuicRecentlyBroken(session_key),
                             params_.retry_on_alternate_network_before_handshake,
                             params_.race_stale_dns_on_connection, priority,
                             cert_verify_flags, net_log);
@@ -2028,11 +2028,12 @@
 }
 
 bool QuicStreamFactory::WasQuicRecentlyBroken(
-    const quic::QuicServerId& server_id) const {
+    const QuicSessionKey& session_key) const {
   const AlternativeService alternative_service(
-      kProtoQUIC, HostPortPair(server_id.host(), server_id.port()));
+      kProtoQUIC, HostPortPair(session_key.server_id().host(),
+                               session_key.server_id().port()));
   return http_server_properties_->WasAlternativeServiceRecentlyBroken(
-      alternative_service);
+      alternative_service, session_key.network_isolation_key());
 }
 
 bool QuicStreamFactory::CryptoConfigCacheIsEmpty(
@@ -2103,11 +2104,16 @@
 
   url::SchemeHostPort server("https", server_id.host(), server_id.port());
   // Do nothing if QUIC is currently marked as broken.
-  if (http_server_properties_->IsAlternativeServiceBroken(alternative_service))
+  if (http_server_properties_->IsAlternativeServiceBroken(
+          alternative_service,
+          session->quic_session_key().network_isolation_key())) {
     return;
+  }
 
   if (session->IsCryptoHandshakeConfirmed()) {
-    http_server_properties_->ConfirmAlternativeService(alternative_service);
+    http_server_properties_->ConfirmAlternativeService(
+        alternative_service,
+        session->quic_session_key().network_isolation_key());
     ServerNetworkStats network_stats;
     network_stats.srtt = base::TimeDelta::FromMicroseconds(stats.srtt_us);
     network_stats.bandwidth_estimate = stats.estimated_bandwidth;
@@ -2138,7 +2144,7 @@
   // avoid not using QUIC when we otherwise could, we mark it as recently
   // broken, which means that 0-RTT will be disabled but we'll still race.
   http_server_properties_->MarkAlternativeServiceRecentlyBroken(
-      alternative_service);
+      alternative_service, session->quic_session_key().network_isolation_key());
 }
 
 }  // namespace net
diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h
index e1b2adb..f46d1673 100644
--- a/net/quic/quic_stream_factory.h
+++ b/net/quic/quic_stream_factory.h
@@ -544,7 +544,7 @@
       const NetworkIsolationKey& network_isolation_key) const;
 
   // Helper methods.
-  bool WasQuicRecentlyBroken(const quic::QuicServerId& server_id) const;
+  bool WasQuicRecentlyBroken(const QuicSessionKey& session_key) const;
 
   bool CryptoConfigCacheIsEmpty(const quic::QuicServerId& server_id);