Remove HTTP Datagram contexts

Since the IETF MASQUE WG decided to remove context IDs from the HTTP Datagram layer, we are removing them from our implementation. This CL is a no-op if contexts were not in use, which was always the case apart from some tests that are deleted by this CL. HTTP Datagrams are currently in use only in WebTransport, and in we only use WebTransport in production as a client, with contexts disabled. This CL is not flag protected because we currently do not have any use of HTTP Datagrams on our servers.

PiperOrigin-RevId: 442018079
diff --git a/quiche/quic/core/http/capsule.cc b/quiche/quic/core/http/capsule.cc
index f17c769..a5aa4f2 100644
--- a/quiche/quic/core/http/capsule.cc
+++ b/quiche/quic/core/http/capsule.cc
@@ -20,14 +20,8 @@
 
 std::string CapsuleTypeToString(CapsuleType capsule_type) {
   switch (capsule_type) {
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      return "REGISTER_DATAGRAM_CONTEXT";
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      return "CLOSE_DATAGRAM_CONTEXT";
     case CapsuleType::LEGACY_DATAGRAM:
       return "LEGACY_DATAGRAM";
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      return "DATAGRAM_WITH_CONTEXT";
     case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
       return "DATAGRAM_WITHOUT_CONTEXT";
     case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
@@ -61,27 +55,6 @@
   return os;
 }
 
-std::string ContextCloseCodeToString(ContextCloseCode context_close_code) {
-  switch (context_close_code) {
-    case ContextCloseCode::CLOSE_NO_ERROR:
-      return "NO_ERROR";
-    case ContextCloseCode::UNKNOWN_FORMAT:
-      return "UNKNOWN_FORMAT";
-    case ContextCloseCode::DENIED:
-      return "DENIED";
-    case ContextCloseCode::RESOURCE_LIMIT:
-      return "RESOURCE_LIMIT";
-  }
-  return absl::StrCat("Unknown(", static_cast<uint64_t>(context_close_code),
-                      ")");
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const ContextCloseCode& context_close_code) {
-  os << ContextCloseCodeToString(context_close_code);
-  return os;
-}
-
 Capsule::Capsule(CapsuleType capsule_type) : capsule_type_(capsule_type) {
   switch (capsule_type) {
     case CapsuleType::LEGACY_DATAGRAM:
@@ -91,13 +64,6 @@
           "All capsule structs must have these properties");
       legacy_datagram_capsule_ = LegacyDatagramCapsule();
       break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      static_assert(
-          std::is_standard_layout<DatagramWithContextCapsule>::value &&
-              std::is_trivially_destructible<DatagramWithContextCapsule>::value,
-          "All capsule structs must have these properties");
-      datagram_with_context_capsule_ = DatagramWithContextCapsule();
-      break;
     case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
       static_assert(
           std::is_standard_layout<DatagramWithoutContextCapsule>::value &&
@@ -106,14 +72,6 @@
           "All capsule structs must have these properties");
       datagram_without_context_capsule_ = DatagramWithoutContextCapsule();
       break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      static_assert(
-          std::is_standard_layout<RegisterDatagramContextCapsule>::value &&
-              std::is_trivially_destructible<
-                  RegisterDatagramContextCapsule>::value,
-          "All capsule structs must have these properties");
-      register_datagram_context_capsule_ = RegisterDatagramContextCapsule();
-      break;
     case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
       static_assert(
           std::is_standard_layout<RegisterDatagramNoContextCapsule>::value &&
@@ -123,14 +81,6 @@
       register_datagram_no_context_capsule_ =
           RegisterDatagramNoContextCapsule();
       break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      static_assert(
-          std::is_standard_layout<CloseDatagramContextCapsule>::value &&
-              std::is_trivially_destructible<
-                  CloseDatagramContextCapsule>::value,
-          "All capsule structs must have these properties");
-      close_datagram_context_capsule_ = CloseDatagramContextCapsule();
-      break;
     case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
       static_assert(
           std::is_standard_layout<CloseWebTransportSessionCapsule>::value &&
@@ -157,16 +107,6 @@
 }
 
 // static
-Capsule Capsule::DatagramWithContext(QuicDatagramContextId context_id,
-                                     absl::string_view http_datagram_payload) {
-  Capsule capsule(CapsuleType::DATAGRAM_WITH_CONTEXT);
-  capsule.datagram_with_context_capsule().context_id = context_id;
-  capsule.datagram_with_context_capsule().http_datagram_payload =
-      http_datagram_payload;
-  return capsule;
-}
-
-// static
 Capsule Capsule::DatagramWithoutContext(
     absl::string_view http_datagram_payload) {
   Capsule capsule(CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
@@ -176,18 +116,6 @@
 }
 
 // static
-Capsule Capsule::RegisterDatagramContext(
-    QuicDatagramContextId context_id, DatagramFormatType format_type,
-    absl::string_view format_additional_data) {
-  Capsule capsule(CapsuleType::REGISTER_DATAGRAM_CONTEXT);
-  capsule.register_datagram_context_capsule().context_id = context_id;
-  capsule.register_datagram_context_capsule().format_type = format_type;
-  capsule.register_datagram_context_capsule().format_additional_data =
-      format_additional_data;
-  return capsule;
-}
-
-// static
 Capsule Capsule::RegisterDatagramNoContext(
     DatagramFormatType format_type, absl::string_view format_additional_data) {
   Capsule capsule(CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
@@ -198,17 +126,6 @@
 }
 
 // static
-Capsule Capsule::CloseDatagramContext(QuicDatagramContextId context_id,
-                                      ContextCloseCode close_code,
-                                      absl::string_view close_details) {
-  Capsule capsule(CapsuleType::CLOSE_DATAGRAM_CONTEXT);
-  capsule.close_datagram_context_capsule().context_id = context_id;
-  capsule.close_datagram_context_capsule().close_code = close_code;
-  capsule.close_datagram_context_capsule().close_details = close_details;
-  return capsule;
-}
-
-// static
 Capsule Capsule::CloseWebTransportSession(WebTransportSessionError error_code,
                                           absl::string_view error_message) {
   Capsule capsule(CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
@@ -231,24 +148,14 @@
     case CapsuleType::LEGACY_DATAGRAM:
       legacy_datagram_capsule_ = other.legacy_datagram_capsule_;
       break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      datagram_with_context_capsule_ = other.datagram_with_context_capsule_;
-      break;
     case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
       datagram_without_context_capsule_ =
           other.datagram_without_context_capsule_;
       break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      register_datagram_context_capsule_ =
-          other.register_datagram_context_capsule_;
-      break;
     case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
       register_datagram_no_context_capsule_ =
           other.register_datagram_no_context_capsule_;
       break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      close_datagram_context_capsule_ = other.close_datagram_context_capsule_;
-      break;
     case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
       close_web_transport_session_capsule_ =
           other.close_web_transport_session_capsule_;
@@ -274,35 +181,15 @@
                  other.legacy_datagram_capsule_.context_id &&
              legacy_datagram_capsule_.http_datagram_payload ==
                  other.legacy_datagram_capsule_.http_datagram_payload;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      return datagram_with_context_capsule_.context_id ==
-                 other.datagram_with_context_capsule_.context_id &&
-             datagram_with_context_capsule_.http_datagram_payload ==
-                 other.datagram_with_context_capsule_.http_datagram_payload;
     case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
       return datagram_without_context_capsule_.http_datagram_payload ==
              other.datagram_without_context_capsule_.http_datagram_payload;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      return register_datagram_context_capsule_.context_id ==
-                 other.register_datagram_context_capsule_.context_id &&
-             register_datagram_context_capsule_.format_type ==
-                 other.register_datagram_context_capsule_.format_type &&
-             register_datagram_context_capsule_.format_additional_data ==
-                 other.register_datagram_context_capsule_
-                     .format_additional_data;
     case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
       return register_datagram_no_context_capsule_.format_type ==
                  other.register_datagram_no_context_capsule_.format_type &&
              register_datagram_no_context_capsule_.format_additional_data ==
                  other.register_datagram_no_context_capsule_
                      .format_additional_data;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      return close_datagram_context_capsule_.context_id ==
-                 other.close_datagram_context_capsule_.context_id &&
-             close_datagram_context_capsule_.close_code ==
-                 other.close_datagram_context_capsule_.close_code &&
-             close_datagram_context_capsule_.close_details ==
-                 other.close_datagram_context_capsule_.close_details;
     case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
       return close_web_transport_session_capsule_.error_code ==
                  other.close_web_transport_session_capsule_.error_code &&
@@ -326,12 +213,6 @@
                           legacy_datagram_capsule_.http_datagram_payload),
                       "]");
       break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      absl::StrAppend(&rv, "(", datagram_with_context_capsule_.context_id, ")[",
-                      absl::BytesToHexString(
-                          datagram_with_context_capsule_.http_datagram_payload),
-                      "]");
-      break;
     case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
       absl::StrAppend(
           &rv, "[",
@@ -339,17 +220,6 @@
               datagram_without_context_capsule_.http_datagram_payload),
           "]");
       break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      absl::StrAppend(
-          &rv, "(context_id=", register_datagram_context_capsule_.context_id,
-          ",format_type=",
-          DatagramFormatTypeToString(
-              register_datagram_context_capsule_.format_type),
-          "){",
-          absl::BytesToHexString(
-              register_datagram_context_capsule_.format_additional_data),
-          "}");
-      break;
     case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
       absl::StrAppend(
           &rv, "(format_type=",
@@ -360,15 +230,6 @@
               register_datagram_no_context_capsule_.format_additional_data),
           "}");
       break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      absl::StrAppend(
-          &rv, "(context_id=", close_datagram_context_capsule_.context_id,
-          ",close_code=",
-          ContextCloseCodeToString(close_datagram_context_capsule_.close_code),
-          ",close_details=\"",
-          absl::BytesToHexString(close_datagram_context_capsule_.close_details),
-          "\")");
-      break;
     case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
       absl::StrAppend(
           &rv, "(error_code=", close_web_transport_session_capsule_.error_code,
@@ -406,26 +267,10 @@
             capsule.legacy_datagram_capsule().context_id.value());
       }
       break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      capsule_data_length =
-          QuicDataWriter::GetVarInt62Len(
-              capsule.datagram_with_context_capsule().context_id) +
-          capsule.datagram_with_context_capsule()
-              .http_datagram_payload.length();
-      break;
     case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
       capsule_data_length = capsule.datagram_without_context_capsule()
                                 .http_datagram_payload.length();
       break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      capsule_data_length =
-          QuicDataWriter::GetVarInt62Len(
-              capsule.register_datagram_context_capsule().context_id) +
-          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
-              capsule.register_datagram_context_capsule().format_type)) +
-          capsule.register_datagram_context_capsule()
-              .format_additional_data.length();
-      break;
     case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
       capsule_data_length =
           QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
@@ -433,14 +278,6 @@
           capsule.register_datagram_no_context_capsule()
               .format_additional_data.length();
       break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      capsule_data_length =
-          QuicDataWriter::GetVarInt62Len(
-              capsule.close_datagram_context_capsule().context_id) +
-          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
-              capsule.close_datagram_context_capsule().close_code)) +
-          capsule.close_datagram_context_capsule().close_details.length();
-      break;
     case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
       capsule_data_length =
           sizeof(WebTransportSessionError) +
@@ -481,20 +318,6 @@
         return {};
       }
       break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      if (!writer.WriteVarInt62(
-              capsule.datagram_with_context_capsule().context_id)) {
-        QUIC_BUG(datagram capsule context ID write fail)
-            << "Failed to write DATAGRAM_WITH_CONTEXT CAPSULE context ID";
-        return {};
-      }
-      if (!writer.WriteStringPiece(
-              capsule.datagram_with_context_capsule().http_datagram_payload)) {
-        QUIC_BUG(datagram capsule payload write fail)
-            << "Failed to write DATAGRAM_WITH_CONTEXT CAPSULE payload";
-        return {};
-      }
-      break;
     case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
       if (!writer.WriteStringPiece(capsule.datagram_without_context_capsule()
                                        .http_datagram_payload)) {
@@ -503,27 +326,6 @@
         return {};
       }
       break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      if (!writer.WriteVarInt62(
-              capsule.register_datagram_context_capsule().context_id)) {
-        QUIC_BUG(register context capsule context ID write fail)
-            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE context ID";
-        return {};
-      }
-      if (!writer.WriteVarInt62(static_cast<uint64_t>(
-              capsule.register_datagram_context_capsule().format_type))) {
-        QUIC_BUG(register context capsule format type write fail)
-            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE format type";
-        return {};
-      }
-      if (!writer.WriteStringPiece(capsule.register_datagram_context_capsule()
-                                       .format_additional_data)) {
-        QUIC_BUG(register context capsule additional data write fail)
-            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE additional "
-               "data";
-        return {};
-      }
-      break;
     case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
       if (!writer.WriteVarInt62(static_cast<uint64_t>(
               capsule.register_datagram_no_context_capsule().format_type))) {
@@ -541,26 +343,6 @@
         return {};
       }
       break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      if (!writer.WriteVarInt62(
-              capsule.close_datagram_context_capsule().context_id)) {
-        QUIC_BUG(close context capsule context ID write fail)
-            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE context ID";
-        return {};
-      }
-      if (!writer.WriteVarInt62(static_cast<uint64_t>(
-              capsule.close_datagram_context_capsule().close_code))) {
-        QUIC_BUG(close context capsule close code write fail)
-            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE close code";
-        return {};
-      }
-      if (!writer.WriteStringPiece(
-              capsule.close_datagram_context_capsule().close_details)) {
-        QUIC_BUG(close context capsule close details write fail)
-            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE close details";
-        return {};
-      }
-      break;
     case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
       if (!writer.WriteUInt32(
               capsule.close_web_transport_session_capsule().error_code)) {
@@ -638,49 +420,13 @@
   Capsule capsule(static_cast<CapsuleType>(capsule_type64));
   switch (capsule.capsule_type()) {
     case CapsuleType::LEGACY_DATAGRAM:
-      if (datagram_context_id_present_) {
-        uint64_t context_id;
-        if (!capsule_data_reader.ReadVarInt62(&context_id)) {
-          ReportParseFailure(
-              "Unable to parse capsule LEGACY_DATAGRAM context ID");
-          return 0;
-        }
-        capsule.legacy_datagram_capsule().context_id = context_id;
-      }
       capsule.legacy_datagram_capsule().http_datagram_payload =
           capsule_data_reader.ReadRemainingPayload();
       break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      uint64_t context_id;
-      if (!capsule_data_reader.ReadVarInt62(&context_id)) {
-        ReportParseFailure(
-            "Unable to parse capsule DATAGRAM_WITH_CONTEXT context ID");
-        return 0;
-      }
-      capsule.datagram_with_context_capsule().context_id = context_id;
-      capsule.datagram_with_context_capsule().http_datagram_payload =
-          capsule_data_reader.ReadRemainingPayload();
-      break;
     case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
       capsule.datagram_without_context_capsule().http_datagram_payload =
           capsule_data_reader.ReadRemainingPayload();
       break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      if (!capsule_data_reader.ReadVarInt62(
-              &capsule.register_datagram_context_capsule().context_id)) {
-        ReportParseFailure(
-            "Unable to parse capsule REGISTER_DATAGRAM_CONTEXT context ID");
-        return 0;
-      }
-      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
-              &capsule.register_datagram_context_capsule().format_type))) {
-        ReportParseFailure(
-            "Unable to parse capsule REGISTER_DATAGRAM_CONTEXT format type");
-        return 0;
-      }
-      capsule.register_datagram_context_capsule().format_additional_data =
-          capsule_data_reader.ReadRemainingPayload();
-      break;
     case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
       if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
               &capsule.register_datagram_no_context_capsule().format_type))) {
@@ -691,22 +437,6 @@
       capsule.register_datagram_no_context_capsule().format_additional_data =
           capsule_data_reader.ReadRemainingPayload();
       break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      if (!capsule_data_reader.ReadVarInt62(
-              &capsule.close_datagram_context_capsule().context_id)) {
-        ReportParseFailure(
-            "Unable to parse capsule CLOSE_DATAGRAM_CONTEXT context ID");
-        return 0;
-      }
-      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
-              &capsule.close_datagram_context_capsule().close_code))) {
-        ReportParseFailure(
-            "Unable to parse capsule CLOSE_DATAGRAM_CONTEXT close code");
-        return 0;
-      }
-      capsule.close_datagram_context_capsule().close_details =
-          capsule_data_reader.ReadRemainingPayload();
-      break;
     case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
       if (!capsule_data_reader.ReadUInt32(
               &capsule.close_web_transport_session_capsule().error_code)) {
diff --git a/quiche/quic/core/http/capsule.h b/quiche/quic/core/http/capsule.h
index 5a93bd3..5eec5d7 100644
--- a/quiche/quic/core/http/capsule.h
+++ b/quiche/quic/core/http/capsule.h
@@ -20,12 +20,11 @@
 
 enum class CapsuleType : uint64_t {
   // Casing in this enum matches the IETF specification.
-  LEGACY_DATAGRAM = 0xff37a0,  // draft-ietf-masque-h3-datagram-04
-  REGISTER_DATAGRAM_CONTEXT = 0xff37a1,
-  REGISTER_DATAGRAM_NO_CONTEXT = 0xff37a2,
-  CLOSE_DATAGRAM_CONTEXT = 0xff37a3,
-  DATAGRAM_WITH_CONTEXT = 0xff37a4,
-  DATAGRAM_WITHOUT_CONTEXT = 0xff37a5,
+  LEGACY_DATAGRAM = 0xff37a0,  // draft-ietf-masque-h3-datagram-04.
+  REGISTER_DATAGRAM_NO_CONTEXT =
+      0xff37a2,  // draft-ietf-masque-h3-datagram-04 to -05.
+  DATAGRAM_WITHOUT_CONTEXT =
+      0xff37a5,  // draft-ietf-masque-h3-datagram-05 to -08.
   CLOSE_WEBTRANSPORT_SESSION = 0x2843,
 };
 
@@ -44,44 +43,17 @@
 QUIC_EXPORT_PRIVATE std::ostream& operator<<(
     std::ostream& os, const DatagramFormatType& datagram_format_type);
 
-enum class ContextCloseCode : uint64_t {
-  // Casing in this enum matches the IETF specification.
-  CLOSE_NO_ERROR = 0xff78a0,  // NO_ERROR already exists in winerror.h.
-  UNKNOWN_FORMAT = 0xff78a1,
-  DENIED = 0xff78a2,
-  RESOURCE_LIMIT = 0xff78a3,
-};
-
-QUIC_EXPORT_PRIVATE std::string ContextCloseCodeToString(
-    ContextCloseCode context_close_code);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os, const ContextCloseCode& context_close_code);
-
 struct QUIC_EXPORT_PRIVATE LegacyDatagramCapsule {
   absl::optional<QuicDatagramContextId> context_id;
   absl::string_view http_datagram_payload;
 };
-struct QUIC_EXPORT_PRIVATE DatagramWithContextCapsule {
-  QuicDatagramContextId context_id;
-  absl::string_view http_datagram_payload;
-};
 struct QUIC_EXPORT_PRIVATE DatagramWithoutContextCapsule {
   absl::string_view http_datagram_payload;
 };
-struct QUIC_EXPORT_PRIVATE RegisterDatagramContextCapsule {
-  QuicDatagramContextId context_id;
-  DatagramFormatType format_type;
-  absl::string_view format_additional_data;
-};
 struct QUIC_EXPORT_PRIVATE RegisterDatagramNoContextCapsule {
   DatagramFormatType format_type;
   absl::string_view format_additional_data;
 };
-struct QUIC_EXPORT_PRIVATE CloseDatagramContextCapsule {
-  QuicDatagramContextId context_id;
-  ContextCloseCode close_code;
-  absl::string_view close_details;
-};
 struct QUIC_EXPORT_PRIVATE CloseWebTransportSessionCapsule {
   WebTransportSessionError error_code;
   absl::string_view error_message;
@@ -97,21 +69,11 @@
   static Capsule LegacyDatagram(
       absl::optional<QuicDatagramContextId> context_id = absl::nullopt,
       absl::string_view http_datagram_payload = absl::string_view());
-  static Capsule DatagramWithContext(
-      QuicDatagramContextId context_id,
-      absl::string_view http_datagram_payload = absl::string_view());
   static Capsule DatagramWithoutContext(
       absl::string_view http_datagram_payload = absl::string_view());
-  static Capsule RegisterDatagramContext(
-      QuicDatagramContextId context_id, DatagramFormatType format_type,
-      absl::string_view format_additional_data = absl::string_view());
   static Capsule RegisterDatagramNoContext(
       DatagramFormatType format_type,
       absl::string_view format_additional_data = absl::string_view());
-  static Capsule CloseDatagramContext(
-      QuicDatagramContextId context_id,
-      ContextCloseCode close_code = ContextCloseCode::CLOSE_NO_ERROR,
-      absl::string_view close_details = absl::string_view());
   static Capsule CloseWebTransportSession(
       WebTransportSessionError error_code = 0,
       absl::string_view error_message = "");
@@ -138,14 +100,6 @@
     QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::LEGACY_DATAGRAM);
     return legacy_datagram_capsule_;
   }
-  DatagramWithContextCapsule& datagram_with_context_capsule() {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITH_CONTEXT);
-    return datagram_with_context_capsule_;
-  }
-  const DatagramWithContextCapsule& datagram_with_context_capsule() const {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITH_CONTEXT);
-    return datagram_with_context_capsule_;
-  }
   DatagramWithoutContextCapsule& datagram_without_context_capsule() {
     QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
     return datagram_without_context_capsule_;
@@ -155,15 +109,6 @@
     QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
     return datagram_without_context_capsule_;
   }
-  RegisterDatagramContextCapsule& register_datagram_context_capsule() {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_CONTEXT);
-    return register_datagram_context_capsule_;
-  }
-  const RegisterDatagramContextCapsule& register_datagram_context_capsule()
-      const {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_CONTEXT);
-    return register_datagram_context_capsule_;
-  }
   RegisterDatagramNoContextCapsule& register_datagram_no_context_capsule() {
     QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
     return register_datagram_no_context_capsule_;
@@ -173,14 +118,6 @@
     QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
     return register_datagram_no_context_capsule_;
   }
-  CloseDatagramContextCapsule& close_datagram_context_capsule() {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_DATAGRAM_CONTEXT);
-    return close_datagram_context_capsule_;
-  }
-  const CloseDatagramContextCapsule& close_datagram_context_capsule() const {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_DATAGRAM_CONTEXT);
-    return close_datagram_context_capsule_;
-  }
   CloseWebTransportSessionCapsule& close_web_transport_session_capsule() {
     QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
     return close_web_transport_session_capsule_;
@@ -192,22 +129,16 @@
   }
   absl::string_view& unknown_capsule_data() {
     QUICHE_DCHECK(capsule_type_ != CapsuleType::LEGACY_DATAGRAM &&
-                  capsule_type_ != CapsuleType::DATAGRAM_WITH_CONTEXT &&
                   capsule_type_ != CapsuleType::DATAGRAM_WITHOUT_CONTEXT &&
-                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_CONTEXT &&
                   capsule_type_ != CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT &&
-                  capsule_type_ != CapsuleType::CLOSE_DATAGRAM_CONTEXT &&
                   capsule_type_ != CapsuleType::CLOSE_WEBTRANSPORT_SESSION)
         << capsule_type_;
     return unknown_capsule_data_;
   }
   const absl::string_view& unknown_capsule_data() const {
     QUICHE_DCHECK(capsule_type_ != CapsuleType::LEGACY_DATAGRAM &&
-                  capsule_type_ != CapsuleType::DATAGRAM_WITH_CONTEXT &&
                   capsule_type_ != CapsuleType::DATAGRAM_WITHOUT_CONTEXT &&
-                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_CONTEXT &&
                   capsule_type_ != CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT &&
-                  capsule_type_ != CapsuleType::CLOSE_DATAGRAM_CONTEXT &&
                   capsule_type_ != CapsuleType::CLOSE_WEBTRANSPORT_SESSION)
         << capsule_type_;
     return unknown_capsule_data_;
@@ -217,11 +148,8 @@
   CapsuleType capsule_type_;
   union {
     LegacyDatagramCapsule legacy_datagram_capsule_;
-    DatagramWithContextCapsule datagram_with_context_capsule_;
     DatagramWithoutContextCapsule datagram_without_context_capsule_;
-    RegisterDatagramContextCapsule register_datagram_context_capsule_;
     RegisterDatagramNoContextCapsule register_datagram_no_context_capsule_;
-    CloseDatagramContextCapsule close_datagram_context_capsule_;
     CloseWebTransportSessionCapsule close_web_transport_session_capsule_;
     absl::string_view unknown_capsule_data_;
   };
@@ -252,10 +180,6 @@
   // |visitor| must be non-null, and must outlive CapsuleParser.
   explicit CapsuleParser(Visitor* visitor);
 
-  void set_datagram_context_id_present(bool datagram_context_id_present) {
-    datagram_context_id_present_ = datagram_context_id_present;
-  }
-
   // Ingests a capsule fragment (any fragment of bytes from the capsule data
   // stream) and parses and complete capsules it encounters. Returns false if a
   // parsing error occurred.
@@ -272,8 +196,6 @@
   size_t AttemptParseCapsule();
   void ReportParseFailure(const std::string& error_message);
 
-  // Whether HTTP Datagram Context IDs are present.
-  bool datagram_context_id_present_ = false;
   // Whether a parsing error has occurred.
   bool parsing_error_occurred_ = false;
   // Visitor which will receive callbacks, unowned.
diff --git a/quiche/quic/core/http/capsule_test.cc b/quiche/quic/core/http/capsule_test.cc
index 895f275..d1f1792a 100644
--- a/quiche/quic/core/http/capsule_test.cc
+++ b/quiche/quic/core/http/capsule_test.cc
@@ -33,8 +33,6 @@
 
 constexpr DatagramFormatType kFakeFormatType =
     static_cast<DatagramFormatType>(0x123456);
-constexpr ContextCloseCode kFakeCloseCode =
-    static_cast<ContextCloseCode>(0x654321);
 
 class MockCapsuleParserVisitor : public CapsuleParser::Visitor {
  public:
@@ -89,25 +87,6 @@
   TestSerialization(expected_capsule, capsule_fragment);
 }
 
-TEST_F(CapsuleTest, LegacyDatagramCapsuleWithContext) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a0"          // LEGACY_DATAGRAM capsule type
-      "09"                // capsule length
-      "04"                // context ID
-      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
-  );
-  capsule_parser_.set_datagram_context_id_present(true);
-  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
-  Capsule expected_capsule =
-      Capsule::LegacyDatagram(/*context_id=*/4, datagram_payload);
-  {
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-  TestSerialization(expected_capsule, capsule_fragment);
-}
-
 TEST_F(CapsuleTest, DatagramWithoutContextCapsule) {
   std::string capsule_fragment = absl::HexStringToBytes(
       "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
@@ -124,44 +103,6 @@
   TestSerialization(expected_capsule, capsule_fragment);
 }
 
-TEST_F(CapsuleTest, DatagramWithContextCapsule) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a4"          // DATAGRAM_WITH_CONTEXT capsule type
-      "09"                // capsule length
-      "04"                // context ID
-      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
-  );
-  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
-  Capsule expected_capsule =
-      Capsule::DatagramWithContext(/*context_id=*/4, datagram_payload);
-  {
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-  TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, RegisterContextCapsule) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a1"          // REGISTER_DATAGRAM_CONTEXT capsule type
-      "0d"                // capsule length
-      "04"                // context ID
-      "80123456"          // 0x123456 datagram format type
-      "f1f2f3f4f5f6f7f8"  // format additional data
-  );
-  std::string format_additional_data =
-      absl::HexStringToBytes("f1f2f3f4f5f6f7f8");
-  Capsule expected_capsule = Capsule::RegisterDatagramContext(
-      /*context_id=*/4, kFakeFormatType, format_additional_data);
-  {
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-  TestSerialization(expected_capsule, capsule_fragment);
-}
-
 TEST_F(CapsuleTest, RegisterNoContextCapsule) {
   std::string capsule_fragment = absl::HexStringToBytes(
       "80ff37a2"          // REGISTER_DATAGRAM_NO_CONTEXT capsule type
@@ -181,25 +122,6 @@
   TestSerialization(expected_capsule, capsule_fragment);
 }
 
-TEST_F(CapsuleTest, CloseContextCapsule) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a3"  // CLOSE_DATAGRAM_CONTEXT capsule type
-      "27"        // capsule length
-      "04"        // context ID
-      "80654321"  // 0x654321 close code
-  );
-  std::string close_details = "All your contexts are belong to us";
-  capsule_fragment += close_details;
-  Capsule expected_capsule = Capsule::CloseDatagramContext(
-      /*context_id=*/4, kFakeCloseCode, close_details);
-  {
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-  TestSerialization(expected_capsule, capsule_fragment);
-}
-
 TEST_F(CapsuleTest, CloseWebTransportStreamCapsule) {
   std::string capsule_fragment = absl::HexStringToBytes(
       "6843"        // CLOSE_WEBTRANSPORT_STREAM capsule type
diff --git a/quiche/quic/core/http/end_to_end_test.cc b/quiche/quic/core/http/end_to_end_test.cc
index ded3d87..7eb3c79 100644
--- a/quiche/quic/core/http/end_to_end_test.cc
+++ b/quiche/quic/core/http/end_to_end_test.cc
@@ -227,7 +227,6 @@
     client->UseClientConnectionIdLength(override_client_connection_id_length_);
     client->client()->set_connection_debug_visitor(connection_debug_visitor_);
     client->client()->set_enable_web_transport(enable_web_transport_);
-    client->client()->set_use_datagram_contexts(use_datagram_contexts_);
     client->Connect();
     return client;
   }
@@ -367,9 +366,6 @@
     if (enable_web_transport_) {
       memory_cache_backend_.set_enable_webtransport(true);
     }
-    if (use_datagram_contexts_) {
-      memory_cache_backend_.set_use_datagram_contexts(true);
-    }
 
     QuicTagVector copt;
     server_config_.SetConnectionOptionsToSend(copt);
@@ -828,7 +824,6 @@
   int override_client_connection_id_length_ = -1;
   uint8_t expected_server_connection_id_length_;
   bool enable_web_transport_ = false;
-  bool use_datagram_contexts_ = false;
   std::vector<std::string> received_webtransport_unidirectional_streams_;
 };
 
@@ -6574,38 +6569,6 @@
   EXPECT_GT(received, 0);
 }
 
-TEST_P(EndToEndTest, WebTransportDatagramsWithContexts) {
-  enable_web_transport_ = true;
-  use_datagram_contexts_ = true;
-  SetPacketLossPercentage(30);
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  QuicSpdyStream* connect_stream = nullptr;
-  WebTransportHttp3* session = CreateWebTransportSession(
-      "/echo", /*wait_for_server_response=*/true, &connect_stream);
-  ASSERT_TRUE(session != nullptr);
-  ASSERT_TRUE(connect_stream != nullptr);
-  NiceMock<MockWebTransportSessionVisitor>& visitor =
-      SetupWebTransportVisitor(session);
-
-  quiche::SimpleBufferAllocator allocator;
-  for (int i = 0; i < 10; i++) {
-    session->SendOrQueueDatagram(MemSliceFromString("test"));
-  }
-
-  int received = 0;
-  EXPECT_CALL(visitor, OnDatagramReceived(_)).WillRepeatedly([&received]() {
-    received++;
-  });
-  client_->WaitUntil(5000, [&received]() { return received > 0; });
-  EXPECT_GT(received, 0);
-  EXPECT_TRUE(QuicSpdyStreamPeer::use_datagram_contexts(connect_stream));
-}
-
 TEST_P(EndToEndTest, WebTransportSessionClose) {
   enable_web_transport_ = true;
   ASSERT_TRUE(Initialize());
diff --git a/quiche/quic/core/http/quic_spdy_session.cc b/quiche/quic/core/http/quic_spdy_session.cc
index 14550db..f757f48 100644
--- a/quiche/quic/core/http/quic_spdy_session.cc
+++ b/quiche/quic/core/http/quic_spdy_session.cc
@@ -880,8 +880,6 @@
 
 bool QuicSpdySession::ShouldNegotiateWebTransport() { return false; }
 
-bool QuicSpdySession::ShouldNegotiateDatagramContexts() { return false; }
-
 bool QuicSpdySession::ShouldValidateWebTransportVersion() const { return true; }
 
 bool QuicSpdySession::WillNegotiateWebTransport() {
@@ -1658,7 +1656,6 @@
 
 MessageStatus QuicSpdySession::SendHttp3Datagram(
     QuicDatagramStreamId stream_id,
-    absl::optional<QuicDatagramContextId> context_id,
     absl::string_view payload) {
   if (!SupportsH3Datagram()) {
     QUIC_BUG(send http datagram too early)
@@ -1672,9 +1669,6 @@
   }
   size_t slice_length =
       QuicDataWriter::GetVarInt62Len(stream_id_to_write) + payload.length();
-  if (context_id.has_value()) {
-    slice_length += QuicDataWriter::GetVarInt62Len(context_id.value());
-  }
   quiche::QuicheBuffer buffer(
       connection()->helper()->GetStreamSendBufferAllocator(), slice_length);
   QuicDataWriter writer(slice_length, buffer.data());
@@ -1683,13 +1677,6 @@
         << "Failed to write HTTP/3 datagram stream ID";
     return MESSAGE_STATUS_INTERNAL_ERROR;
   }
-  if (context_id.has_value()) {
-    if (!writer.WriteVarInt62(context_id.value())) {
-      QUIC_BUG(h3 datagram context ID write fail)
-          << "Failed to write HTTP/3 datagram context ID";
-      return MESSAGE_STATUS_INTERNAL_ERROR;
-    }
-  }
   if (!writer.WriteBytes(payload.data(), payload.length())) {
     QUIC_BUG(h3 datagram payload write fail)
         << "Failed to write HTTP/3 datagram payload";
diff --git a/quiche/quic/core/http/quic_spdy_session.h b/quiche/quic/core/http/quic_spdy_session.h
index b603803..0807905 100644
--- a/quiche/quic/core/http/quic_spdy_session.h
+++ b/quiche/quic/core/http/quic_spdy_session.h
@@ -391,7 +391,6 @@
   // This must not be used except by QuicSpdyStream::SendHttp3Datagram.
   MessageStatus SendHttp3Datagram(
       QuicDatagramStreamId stream_id,
-      absl::optional<QuicDatagramContextId> context_id,
       absl::string_view payload);
   // This must not be used except by QuicSpdyStream::SetMaxDatagramTimeInQueue.
   void SetMaxDatagramTimeInQueueForStreamId(QuicStreamId stream_id,
@@ -462,10 +461,6 @@
 
   QuicSpdyStream* GetOrCreateSpdyDataStream(const QuicStreamId stream_id);
 
-  // Indicates whether we will try to negotiate datagram contexts on newly
-  // created WebTransport sessions over HTTP/3.
-  virtual bool ShouldNegotiateDatagramContexts();
-
   // Indicates whether the client should check that the
   // `Sec-Webtransport-Http3-Draft` header is valid.
   // TODO(vasilvv): remove this once this is enabled in Chromium.
diff --git a/quiche/quic/core/http/quic_spdy_stream.cc b/quiche/quic/core/http/quic_spdy_stream.cc
index 82077cd..db8b178 100644
--- a/quiche/quic/core/http/quic_spdy_stream.cc
+++ b/quiche/quic/core/http/quic_spdy_stream.cc
@@ -193,11 +193,7 @@
       sequencer_offset_(0),
       is_decoder_processing_input_(false),
       ack_listener_(nullptr),
-      last_sent_urgency_(kDefaultUrgency),
-      datagram_next_available_context_id_(spdy_session->perspective() ==
-                                                  Perspective::IS_SERVER
-                                              ? kFirstDatagramContextIdServer
-                                              : kFirstDatagramContextIdClient) {
+      last_sent_urgency_(kDefaultUrgency) {
   QUICHE_DCHECK_EQ(session()->connection(), spdy_session->connection());
   QUICHE_DCHECK_EQ(transport_version(), spdy_session->transport_version());
   QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
@@ -253,13 +249,6 @@
 
 QuicSpdyStream::~QuicSpdyStream() {}
 
-bool QuicSpdyStream::ShouldUseDatagramContexts() const {
-  return spdy_session_->SupportsH3Datagram() &&
-         spdy_session_->http_datagram_support() !=
-             HttpDatagramSupport::kDraft00 &&
-         use_datagram_contexts_;
-}
-
 size_t QuicSpdyStream::WriteHeaders(
     SpdyHeaderBlock header_block, bool fin,
     quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
@@ -288,12 +277,6 @@
 
   MaybeProcessSentWebTransportHeaders(header_block);
 
-  if (ShouldUseDatagramContexts()) {
-    // RegisterHttp3DatagramRegistrationVisitor caller wishes to use contexts,
-    // inform the peer.
-    header_block["sec-use-datagram-contexts"] = "?1";
-  }
-
   if (web_transport_ != nullptr &&
       spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00 &&
       spdy_session_->perspective() == Perspective::IS_SERVER) {
@@ -313,11 +296,20 @@
 
   if (web_transport_ != nullptr &&
       session()->perspective() == Perspective::IS_CLIENT) {
-    // This will send a capsule and therefore needs to happen after headers have
-    // been sent.
-    RegisterHttp3DatagramContextId(
-        web_transport_->context_id(), DatagramFormatType::WEBTRANSPORT,
-        /*format_additional_data=*/absl::string_view(), web_transport_.get());
+    if (spdy_session_->http_datagram_support() !=
+        HttpDatagramSupport::kDraft00) {
+      // draft-ietf-masque-h3-datagram-01 and later use capsules.
+      WriteGreaseCapsule();
+      if (spdy_session_->http_datagram_support() ==
+          HttpDatagramSupport::kDraft04) {
+        // Send a REGISTER_DATAGRAM_NO_CONTEXT capsule to support servers that
+        // are running draft-ietf-masque-h3-datagram-04 or -05.
+        WriteCapsule(Capsule::RegisterDatagramNoContext(
+            DatagramFormatType::WEBTRANSPORT,
+            /*format_additional_data=*/absl::string_view()));
+        WriteGreaseCapsule();
+      }
+    }
   }
 
   return bytes_written;
@@ -654,19 +646,6 @@
   if (!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
       !header_too_large) {
     MaybeProcessReceivedWebTransportHeaders();
-    if (ShouldUseDatagramContexts()) {
-      bool peer_wishes_to_use_datagram_contexts = false;
-      for (const auto& header : header_list_) {
-        if (header.first == "sec-use-datagram-contexts" &&
-            header.second == "?1") {
-          peer_wishes_to_use_datagram_contexts = true;
-          break;
-        }
-      }
-      if (!peer_wishes_to_use_datagram_contexts) {
-        use_datagram_contexts_ = false;
-      }
-    }
   }
 
   if (VersionUsesHttp3(transport_version())) {
@@ -1340,20 +1319,8 @@
     RegisterHttp3DatagramFlowId(*flow_id);
   }
 
-  web_transport_ = std::make_unique<WebTransportHttp3>(
-      spdy_session_, this, id(),
-      spdy_session_->ShouldNegotiateDatagramContexts());
-
-  if (spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00) {
-    return;
-  }
-  // If we're in draft-ietf-masque-h3-datagram-00 mode, pretend we also received
-  // a REGISTER_DATAGRAM_NO_CONTEXT capsule.
-  // TODO(b/181256914) remove this when we remove support for
-  // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
-  RegisterHttp3DatagramContextId(
-      /*context_id=*/absl::nullopt, DatagramFormatType::WEBTRANSPORT,
-      /*format_additional_data=*/absl::string_view(), web_transport_.get());
+  web_transport_ =
+      std::make_unique<WebTransportHttp3>(spdy_session_, this, id());
 }
 
 void QuicSpdyStream::MaybeProcessSentWebTransportHeaders(
@@ -1381,9 +1348,8 @@
     headers["sec-webtransport-http3-draft02"] = "1";
   }
 
-  web_transport_ = std::make_unique<WebTransportHttp3>(
-      spdy_session_, this, id(),
-      spdy_session_->ShouldNegotiateDatagramContexts());
+  web_transport_ =
+      std::make_unique<WebTransportHttp3>(spdy_session_, this, id());
 }
 
 void QuicSpdyStream::OnCanWriteNewData() {
@@ -1444,27 +1410,12 @@
       adapter(stream->spdy_session_, stream, stream->sequencer()) {}
 
 void QuicSpdyStream::HandleReceivedDatagram(
-    absl::optional<QuicDatagramContextId> context_id,
     absl::string_view payload) {
-  Http3DatagramVisitor* visitor;
-  if (context_id.has_value()) {
-    auto it = datagram_context_visitors_.find(context_id.value());
-    if (it == datagram_context_visitors_.end()) {
-      QUIC_DLOG(ERROR) << ENDPOINT
-                       << "Received datagram without any visitor for context "
-                       << context_id.value();
-      return;
-    }
-    visitor = it->second;
-  } else {
-    if (datagram_no_context_visitor_ == nullptr) {
-      QUIC_DLOG(ERROR)
-          << ENDPOINT << "Received datagram without any visitor for no context";
-      return;
-    }
-    visitor = datagram_no_context_visitor_;
+  if (datagram_visitor_ == nullptr) {
+    QUIC_DLOG(ERROR) << ENDPOINT << "Received datagram without any visitor";
+    return;
   }
-  visitor->OnHttp3Datagram(id(), context_id, payload);
+  datagram_visitor_->OnHttp3Datagram(id(), payload);
 }
 
 bool QuicSpdyStream::OnCapsule(const Capsule& capsule) {
@@ -1485,64 +1436,14 @@
   switch (capsule.capsule_type()) {
     case CapsuleType::LEGACY_DATAGRAM: {
       HandleReceivedDatagram(
-          capsule.legacy_datagram_capsule().context_id,
           capsule.legacy_datagram_capsule().http_datagram_payload);
     } break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT: {
-      HandleReceivedDatagram(
-          capsule.datagram_with_context_capsule().context_id,
-          capsule.datagram_with_context_capsule().http_datagram_payload);
-    } break;
     case CapsuleType::DATAGRAM_WITHOUT_CONTEXT: {
-      absl::optional<QuicDatagramContextId> context_id;
-      if (use_datagram_contexts_) {
-        // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
-        // DATAGRAM_WITHOUT_CONTEXT.
-        context_id = 0;
-      }
       HandleReceivedDatagram(
-          context_id,
           capsule.datagram_without_context_capsule().http_datagram_payload);
     } break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT: {
-      if (datagram_registration_visitor_ == nullptr) {
-        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
-                         << " without any registration visitor";
-        return false;
-      }
-      datagram_registration_visitor_->OnContextReceived(
-          id(), capsule.register_datagram_context_capsule().context_id,
-          capsule.register_datagram_context_capsule().format_type,
-          capsule.register_datagram_context_capsule().format_additional_data);
-    } break;
     case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT: {
-      if (datagram_registration_visitor_ == nullptr) {
-        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
-                         << " without any registration visitor";
-        return false;
-      }
-      absl::optional<QuicDatagramContextId> context_id;
-      if (use_datagram_contexts_) {
-        // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
-        // REGISTER_DATAGRAM_NO_CONTEXT.
-        context_id = 0;
-      }
-      datagram_registration_visitor_->OnContextReceived(
-          id(), context_id,
-          capsule.register_datagram_no_context_capsule().format_type,
-          capsule.register_datagram_no_context_capsule()
-              .format_additional_data);
-    } break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT: {
-      if (datagram_registration_visitor_ == nullptr) {
-        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
-                         << " without any registration visitor";
-        return false;
-      }
-      datagram_registration_visitor_->OnContextClosed(
-          id(), capsule.close_datagram_context_capsule().context_id,
-          capsule.close_datagram_context_capsule().close_code,
-          capsule.close_datagram_context_capsule().close_details);
+      // Silently ignore received REGISTER_DATAGRAM_NO_CONTEXT capsules.
     } break;
     case CapsuleType::CLOSE_WEBTRANSPORT_SESSION: {
       if (web_transport_ == nullptr) {
@@ -1589,201 +1490,52 @@
 }
 
 MessageStatus QuicSpdyStream::SendHttp3Datagram(
-    absl::optional<QuicDatagramContextId> context_id,
     absl::string_view payload) {
   QuicDatagramStreamId stream_id =
       datagram_flow_id_.has_value() ? datagram_flow_id_.value() : id();
-  return spdy_session_->SendHttp3Datagram(stream_id, context_id, payload);
+  return spdy_session_->SendHttp3Datagram(stream_id, payload);
 }
 
-void QuicSpdyStream::RegisterHttp3DatagramRegistrationVisitor(
-    Http3DatagramRegistrationVisitor* visitor, bool use_datagram_contexts) {
-  if (visitor == nullptr) {
-    QUIC_BUG(null datagram registration visitor)
-        << ENDPOINT << "Null datagram registration visitor for" << id();
-    return;
-  }
-  if (datagram_registration_visitor_ != nullptr) {
-    QUIC_BUG(double datagram registration visitor)
-        << ENDPOINT << "Double datagram registration visitor for" << id();
-    return;
-  }
-  use_datagram_contexts_ = use_datagram_contexts;
-  QUIC_DLOG(INFO) << ENDPOINT << "Registering datagram stream ID " << id()
-                  << " with" << (use_datagram_contexts_ ? "" : "out")
-                  << " contexts";
-  datagram_registration_visitor_ = visitor;
-  QUICHE_DCHECK(!capsule_parser_);
-  capsule_parser_.reset(new CapsuleParser(this));
-}
-
-void QuicSpdyStream::UnregisterHttp3DatagramRegistrationVisitor() {
-  QUIC_BUG_IF(h3 datagram unregister unknown stream ID,
-              datagram_registration_visitor_ == nullptr)
-      << ENDPOINT
-      << "Attempted to unregister unknown HTTP/3 datagram stream ID " << id();
-  QUIC_DLOG(INFO) << ENDPOINT << "Unregistering datagram stream ID " << id();
-  datagram_registration_visitor_ = nullptr;
-}
-
-void QuicSpdyStream::MoveHttp3DatagramRegistration(
-    Http3DatagramRegistrationVisitor* visitor) {
-  QUIC_BUG_IF(h3 datagram move unknown stream ID,
-              datagram_registration_visitor_ == nullptr)
-      << ENDPOINT << "Attempted to move unknown HTTP/3 datagram stream ID "
-      << id();
-  QUIC_DLOG(INFO) << ENDPOINT << "Moving datagram stream ID " << id();
-  datagram_registration_visitor_ = visitor;
-}
-
-void QuicSpdyStream::RegisterHttp3DatagramContextId(
-    absl::optional<QuicDatagramContextId> context_id,
-    DatagramFormatType format_type, absl::string_view format_additional_data,
+void QuicSpdyStream::RegisterHttp3DatagramVisitor(
     Http3DatagramVisitor* visitor) {
   if (visitor == nullptr) {
     QUIC_BUG(null datagram visitor)
-        << ENDPOINT << "Null datagram visitor for stream ID " << id()
-        << " context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none");
+        << ENDPOINT << "Null datagram visitor for stream ID " << id();
     return;
   }
-  if (datagram_registration_visitor_ == nullptr) {
-    QUIC_BUG(context registration without registration visitor)
-        << ENDPOINT << "Cannot register context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " without registration visitor for stream ID " << id();
-    return;
-  }
-  QUIC_DLOG(INFO) << ENDPOINT << "Registering datagram context ID "
-                  << (context_id.has_value() ? absl::StrCat(context_id.value())
-                                             : "none")
-                  << " with stream ID " << id();
+  QUIC_DLOG(INFO) << ENDPOINT << "Registering datagram visitor with stream ID "
+                  << id();
 
-  if (context_id.has_value()) {
-    if (datagram_no_context_visitor_ != nullptr) {
-      QUIC_BUG(h3 datagram context ID mix1)
-          << ENDPOINT
-          << "Attempted to mix registrations without and with context IDs "
-             "for stream ID "
-          << id();
-      return;
-    }
-    auto insertion_result =
-        datagram_context_visitors_.insert({context_id.value(), visitor});
-    if (!insertion_result.second) {
-      QUIC_BUG(h3 datagram double context registration)
-          << ENDPOINT << "Attempted to doubly register HTTP/3 stream ID "
-          << id() << " context ID " << context_id.value();
-      return;
-    }
-    capsule_parser_->set_datagram_context_id_present(true);
-  } else {
-    // Registration without a context ID.
-    if (!datagram_context_visitors_.empty()) {
-      QUIC_BUG(h3 datagram context ID mix2)
-          << ENDPOINT
-          << "Attempted to mix registrations with and without context IDs "
-             "for stream ID "
-          << id();
-      return;
-    }
-    if (datagram_no_context_visitor_ != nullptr) {
-      QUIC_BUG(h3 datagram double no context registration)
-          << ENDPOINT << "Attempted to doubly register HTTP/3 stream ID "
-          << id() << " with no context ID";
-      return;
-    }
-    datagram_no_context_visitor_ = visitor;
-    capsule_parser_->set_datagram_context_id_present(false);
-  }
-  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft04) {
-    const bool is_client = session()->perspective() == Perspective::IS_CLIENT;
-    if (context_id.has_value()) {
-      const bool is_client_context = context_id.value() % 2 == 0;
-      if (is_client == is_client_context) {
-        QuicConnection::ScopedPacketFlusher flusher(
-            spdy_session_->connection());
-        WriteGreaseCapsule();
-        if (context_id.value() != 0) {
-          WriteCapsule(Capsule::RegisterDatagramContext(
-              context_id.value(), format_type, format_additional_data));
-        } else {
-          // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
-          // REGISTER_DATAGRAM_NO_CONTEXT.
-          WriteCapsule(Capsule::RegisterDatagramNoContext(
-              format_type, format_additional_data));
-        }
-        WriteGreaseCapsule();
-      }
-    } else if (is_client) {
-      QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
-      WriteGreaseCapsule();
-      WriteCapsule(Capsule::RegisterDatagramNoContext(format_type,
-                                                      format_additional_data));
-      WriteGreaseCapsule();
-    }
-  }
-}
-
-void QuicSpdyStream::UnregisterHttp3DatagramContextId(
-    absl::optional<QuicDatagramContextId> context_id) {
-  if (datagram_registration_visitor_ == nullptr) {
-    QUIC_BUG(context unregistration without registration visitor)
-        << ENDPOINT << "Cannot unregister context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " without registration visitor for stream ID " << id();
-    return;
-  }
-  QUIC_DLOG(INFO) << ENDPOINT << "Unregistering datagram context ID "
-                  << (context_id.has_value() ? absl::StrCat(context_id.value())
-                                             : "none")
-                  << " with stream ID " << id();
-  if (context_id.has_value()) {
-    size_t num_erased = datagram_context_visitors_.erase(context_id.value());
-    QUIC_BUG_IF(h3 datagram unregister unknown context, num_erased != 1)
-        << "Attempted to unregister unknown HTTP/3 context ID "
-        << context_id.value() << " on stream ID " << id();
-  } else {
-    // Unregistration without a context ID.
-    QUIC_BUG_IF(h3 datagram unknown context unregistration,
-                datagram_no_context_visitor_ == nullptr)
-        << "Attempted to unregister unknown no context on HTTP/3 stream ID "
+  if (datagram_visitor_ != nullptr) {
+    QUIC_BUG(h3 datagram double registration)
+        << ENDPOINT
+        << "Attempted to doubly register HTTP/3 datagram with stream ID "
         << id();
-    datagram_no_context_visitor_ = nullptr;
+    return;
   }
-  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft04 &&
-      context_id.has_value()) {
-    WriteCapsule(Capsule::CloseDatagramContext(context_id.value()));
-  }
+  datagram_visitor_ = visitor;
+  QUICHE_DCHECK(!capsule_parser_);
+  capsule_parser_ = std::make_unique<CapsuleParser>(this);
 }
 
-void QuicSpdyStream::MoveHttp3DatagramContextIdRegistration(
-    absl::optional<QuicDatagramContextId> context_id,
+void QuicSpdyStream::UnregisterHttp3DatagramVisitor() {
+  if (datagram_visitor_ == nullptr) {
+    QUIC_BUG(datagram visitor empty during unregistration)
+        << ENDPOINT << "Cannot unregister datagram visitor for stream ID "
+        << id();
+    return;
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << "Unregistering datagram visitor for stream ID "
+                  << id();
+  datagram_visitor_ = nullptr;
+}
+
+void QuicSpdyStream::ReplaceHttp3DatagramVisitor(
     Http3DatagramVisitor* visitor) {
-  if (datagram_registration_visitor_ == nullptr) {
-    QUIC_BUG(context move without registration visitor)
-        << ENDPOINT << "Cannot move context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " without registration visitor for stream ID " << id();
-    return;
-  }
-  QUIC_DLOG(INFO) << ENDPOINT << "Moving datagram context ID "
-                  << (context_id.has_value() ? absl::StrCat(context_id.value())
-                                             : "none")
-                  << " with stream ID " << id();
-  if (context_id.has_value()) {
-    QUIC_BUG_IF(h3 datagram move unknown context,
-                !datagram_context_visitors_.contains(context_id.value()))
-        << ENDPOINT << "Attempted to move unknown context ID "
-        << context_id.value() << " on stream ID " << id();
-    datagram_context_visitors_[context_id.value()] = visitor;
-    return;
-  }
-  // Move without a context ID.
-  QUIC_BUG_IF(h3 datagram unknown context move,
-              datagram_no_context_visitor_ == nullptr)
-      << "Attempted to move unknown no context on HTTP/3 stream ID " << id();
-  datagram_no_context_visitor_ = visitor;
+  QUIC_BUG_IF(h3 datagram unknown move, datagram_visitor_ == nullptr)
+      << "Attempted to move missing datagram visitor on HTTP/3 stream ID "
+      << id();
+  datagram_visitor_ = visitor;
 }
 
 void QuicSpdyStream::SetMaxDatagramTimeInQueue(
@@ -1791,35 +1543,16 @@
   spdy_session_->SetMaxDatagramTimeInQueueForStreamId(id(), max_time_in_queue);
 }
 
-QuicDatagramContextId QuicSpdyStream::GetNextDatagramContextId() {
-  QuicDatagramContextId result = datagram_next_available_context_id_;
-  datagram_next_available_context_id_ += kDatagramContextIdIncrement;
-  return result;
-}
-
 void QuicSpdyStream::OnDatagramReceived(QuicDataReader* reader) {
   if (!headers_decompressed_) {
     QUIC_DLOG(INFO) << "Dropping datagram received before headers on stream ID "
                     << id();
     return;
   }
-  absl::optional<QuicDatagramContextId> context_id;
-  if (use_datagram_contexts_) {
-    QuicDatagramContextId parsed_context_id;
-    if (!reader->ReadVarInt62(&parsed_context_id)) {
-      QUIC_DLOG(ERROR) << "Failed to parse context ID in received HTTP/3 "
-                          "datagram on stream ID "
-                       << id();
-      return;
-    }
-    context_id = parsed_context_id;
-  }
-  absl::string_view payload = reader->ReadRemainingPayload();
-  HandleReceivedDatagram(context_id, payload);
+  HandleReceivedDatagram(reader->ReadRemainingPayload());
 }
 
-QuicByteCount QuicSpdyStream::GetMaxDatagramSize(
-    absl::optional<QuicDatagramContextId> context_id) const {
+QuicByteCount QuicSpdyStream::GetMaxDatagramSize() const {
   QuicByteCount prefix_size = 0;
   switch (spdy_session_->http_datagram_support()) {
     case HttpDatagramSupport::kDraft00:
@@ -1847,21 +1580,12 @@
     prefix_size = 8;
   }
 
-  if (context_id.has_value()) {
-    QUIC_BUG_IF(
-        context_id with draft00 in GetMaxDatagramSize,
-        spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00)
-        << "GetMaxDatagramSize() called with a context ID specified, but "
-           "draft00 does not support contexts.";
-    prefix_size += QuicDataWriter::GetVarInt62Len(*context_id);
-  }
-
   QuicByteCount max_datagram_size =
       session()->GetGuaranteedLargestMessagePayload();
   if (max_datagram_size < prefix_size) {
     QUIC_BUG(max_datagram_size smaller than prefix_size)
         << "GetGuaranteedLargestMessagePayload() returned a datagram size that "
-           "is not sufficient to fit stream and/or context ID into it.";
+           "is not sufficient to fit stream ID into it.";
     return 0;
   }
   return max_datagram_size - prefix_size;
diff --git a/quiche/quic/core/http/quic_spdy_stream.h b/quiche/quic/core/http/quic_spdy_stream.h
index b7fc714..6e35012 100644
--- a/quiche/quic/core/http/quic_spdy_stream.h
+++ b/quiche/quic/core/http/quic_spdy_stream.h
@@ -254,10 +254,8 @@
   bool OnCapsule(const Capsule& capsule) override;
   void OnCapsuleParseFailure(const std::string& error_message) override;
 
-  // Sends an HTTP/3 datagram. The stream and context IDs are not part of
-  // |payload|.
+  // Sends an HTTP/3 datagram. The stream ID is not part of |payload|.
   MessageStatus SendHttp3Datagram(
-      absl::optional<QuicDatagramContextId> context_id,
       absl::string_view payload);
 
   class QUIC_EXPORT_PRIVATE Http3DatagramVisitor {
@@ -265,87 +263,35 @@
     virtual ~Http3DatagramVisitor() {}
 
     // Called when an HTTP/3 datagram is received. |payload| does not contain
-    // the stream or context IDs. Note that this contains the stream ID even if
-    // flow IDs from draft-ietf-masque-h3-datagram-00 are in use.
+    // the stream ID. Note that this contains the stream ID even if flow IDs
+    // from draft-ietf-masque-h3-datagram-00 are in use.
     virtual void OnHttp3Datagram(
         QuicStreamId stream_id,
-        absl::optional<QuicDatagramContextId> context_id,
         absl::string_view payload) = 0;
   };
 
-  class QUIC_EXPORT_PRIVATE Http3DatagramRegistrationVisitor {
-   public:
-    virtual ~Http3DatagramRegistrationVisitor() {}
+  // Registers |visitor| to receive HTTP/3 datagrams. |visitor| must be
+  // valid until a corresponding call to UnregisterHttp3DatagramVisitor.
+  void RegisterHttp3DatagramVisitor(Http3DatagramVisitor* visitor);
 
-    // Called when a REGISTER_DATAGRAM_CONTEXT or REGISTER_DATAGRAM_NO_CONTEXT
-    // capsule is received. Note that this contains the stream ID even if flow
-    // IDs from draft-ietf-masque-h3-datagram-00 are in use.
-    virtual void OnContextReceived(
-        QuicStreamId stream_id,
-        absl::optional<QuicDatagramContextId> context_id,
-        DatagramFormatType format_type,
-        absl::string_view format_additional_data) = 0;
+  // Unregisters an HTTP/3 datagram visitor. Must only be called after a call to
+  // RegisterHttp3DatagramVisitor.
+  void UnregisterHttp3DatagramVisitor();
 
-    // Called when a CLOSE_DATAGRAM_CONTEXT capsule is received. Note that this
-    // contains the stream ID even if flow IDs from
-    // draft-ietf-masque-h3-datagram-00 are in use.
-    virtual void OnContextClosed(
-        QuicStreamId stream_id,
-        absl::optional<QuicDatagramContextId> context_id,
-        ContextCloseCode close_code, absl::string_view close_details) = 0;
-  };
-
-  // Registers |visitor| to receive HTTP/3 datagram context registrations. This
-  // must not be called without first calling
-  // UnregisterHttp3DatagramRegistrationVisitor. |visitor| must be valid until a
-  // corresponding call to UnregisterHttp3DatagramRegistrationVisitor.
-  void RegisterHttp3DatagramRegistrationVisitor(
-      Http3DatagramRegistrationVisitor* visitor,
-      bool use_datagram_contexts = false);
-
-  // Unregisters for HTTP/3 datagram context registrations. Must not be called
-  // unless previously registered.
-  void UnregisterHttp3DatagramRegistrationVisitor();
-
-  // Moves an HTTP/3 datagram registration to a different visitor. Mainly meant
-  // to be used by the visitors' move operators.
-  void MoveHttp3DatagramRegistration(Http3DatagramRegistrationVisitor* visitor);
-
-  // Registers |visitor| to receive HTTP/3 datagrams for optional context ID
-  // |context_id|. This must not be called on a previously registered context ID
-  // without first calling UnregisterHttp3DatagramContextId. |visitor| must be
-  // valid until a corresponding call to UnregisterHttp3DatagramContextId. If
-  // this method is called multiple times, the context ID MUST either be always
-  // present, or always absent.
-  void RegisterHttp3DatagramContextId(
-      absl::optional<QuicDatagramContextId> context_id,
-      DatagramFormatType format_type, absl::string_view format_additional_data,
-      Http3DatagramVisitor* visitor);
-
-  // Unregisters an HTTP/3 datagram context ID. Must be called on a previously
-  // registered context.
-  void UnregisterHttp3DatagramContextId(
-      absl::optional<QuicDatagramContextId> context_id);
-
-  // Moves an HTTP/3 datagram context ID to a different visitor. Mainly meant
-  // to be used by the visitors' move operators.
-  void MoveHttp3DatagramContextIdRegistration(
-      absl::optional<QuicDatagramContextId> context_id,
-      Http3DatagramVisitor* visitor);
+  // Replaces the current HTTP/3 datagram visitor with a different visitor.
+  // Mainly meant to be used by the visitors' move operators.
+  void ReplaceHttp3DatagramVisitor(Http3DatagramVisitor* visitor);
 
   // Sets max datagram time in queue.
   void SetMaxDatagramTimeInQueue(QuicTime::Delta max_time_in_queue);
 
-  // Generates a new HTTP/3 datagram context ID for this stream. A datagram
-  // registration visitor must be currently registered on this stream.
-  QuicDatagramContextId GetNextDatagramContextId();
-
   void OnDatagramReceived(QuicDataReader* reader);
 
+  // Registers a datagram flow ID, only meant to be used when in legacy mode for
+  // draft-ietf-masque-h3-datagram-00.
   void RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id);
 
-  QuicByteCount GetMaxDatagramSize(
-      absl::optional<QuicDatagramContextId> context_id) const;
+  QuicByteCount GetMaxDatagramSize() const;
 
   // Writes |capsule| onto the DATA stream.
   void WriteCapsule(const Capsule& capsule, bool fin = false);
@@ -445,11 +391,7 @@
   void HandleBodyAvailable();
 
   // Called when a datagram frame or capsule is received.
-  void HandleReceivedDatagram(absl::optional<QuicDatagramContextId> context_id,
-                              absl::string_view payload);
-
-  // Whether datagram contexts should be used on this stream.
-  bool ShouldUseDatagramContexts() const;
+  void HandleReceivedDatagram(absl::string_view payload);
 
   QuicSpdySession* spdy_session_;
 
@@ -526,13 +468,10 @@
   std::unique_ptr<WebTransportDataStream> web_transport_data_;
 
   // HTTP/3 Datagram support.
-  Http3DatagramRegistrationVisitor* datagram_registration_visitor_ = nullptr;
-  Http3DatagramVisitor* datagram_no_context_visitor_ = nullptr;
+  Http3DatagramVisitor* datagram_visitor_ = nullptr;
+  // Flow ID is only used when in legacy mode for
+  // draft-ietf-masque-h3-datagram-00.
   absl::optional<QuicDatagramStreamId> datagram_flow_id_;
-  QuicDatagramContextId datagram_next_available_context_id_;
-  absl::flat_hash_map<QuicDatagramContextId, Http3DatagramVisitor*>
-      datagram_context_visitors_;
-  bool use_datagram_contexts_ = false;
 };
 
 }  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_stream_test.cc b/quiche/quic/core/http/quic_spdy_stream_test.cc
index b0c972d..33b0588 100644
--- a/quiche/quic/core/http/quic_spdy_stream_test.cc
+++ b/quiche/quic/core/http/quic_spdy_stream_test.cc
@@ -3125,8 +3125,6 @@
   stream_->OnStreamHeadersPriority(
       spdy::SpdyStreamPrecedence(kV3HighestPriority));
   ProcessHeaders(false, headers_);
-  stream_->OnCapsule(
-      Capsule::RegisterDatagramNoContext(DatagramFormatType::WEBTRANSPORT));
   EXPECT_EQ("", stream_->data());
   EXPECT_FALSE(stream_->header_list().empty());
   EXPECT_FALSE(stream_->IsDoneReading());
@@ -3189,35 +3187,7 @@
   EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
 }
 
-TEST_P(QuicSpdyStreamTest, GetNextDatagramContextIdClient) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor> visitor;
-  stream_->RegisterHttp3DatagramRegistrationVisitor(&visitor);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 0u);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 2u);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 4u);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 6u);
-  stream_->UnregisterHttp3DatagramRegistrationVisitor();
-}
-
-TEST_P(QuicSpdyStreamTest, GetNextDatagramContextIdServer) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_SERVER);
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor> visitor;
-  stream_->RegisterHttp3DatagramRegistrationVisitor(&visitor);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 1u);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 3u);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 5u);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 7u);
-  stream_->UnregisterHttp3DatagramRegistrationVisitor();
-}
-
-TEST_P(QuicSpdyStreamTest, HttpDatagramRegistrationWithoutContextDraft00) {
+TEST_P(QuicSpdyStreamTest, ReceiveHttpDatagramDraft00) {
   if (!UsesHttp3()) {
     return;
   }
@@ -3230,49 +3200,36 @@
   headers_["datagram-flow-id"] = absl::StrCat(stream_->id());
   ProcessHeaders(false, headers_);
   session_->RegisterHttp3DatagramFlowId(stream_->id(), stream_->id());
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
-      h3_datagram_registration_visitor;
   SavingHttp3DatagramVisitor h3_datagram_visitor;
-  absl::optional<QuicDatagramContextId> context_id;
-  absl::string_view format_additional_data;
   ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
   std::array<char, 256> datagram;
   datagram[0] = stream_->id();
   for (size_t i = 1; i < datagram.size(); i++) {
     datagram[i] = i;
   }
-  stream_->RegisterHttp3DatagramRegistrationVisitor(
-      &h3_datagram_registration_visitor);
-  stream_->RegisterHttp3DatagramContextId(
-      context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
-      &h3_datagram_visitor);
+  stream_->RegisterHttp3DatagramVisitor(&h3_datagram_visitor);
   session_->OnMessageReceived(
       absl::string_view(datagram.data(), datagram.size()));
-  EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
-              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
-                  stream_->id(), context_id,
-                  std::string(&datagram[1], datagram.size() - 1)}));
+  EXPECT_THAT(
+      h3_datagram_visitor.received_h3_datagrams(),
+      ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+          stream_->id(), std::string(&datagram[1], datagram.size() - 1)}));
   // Test move.
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
-      h3_datagram_registration_visitor2;
-  stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
   SavingHttp3DatagramVisitor h3_datagram_visitor2;
-  stream_->MoveHttp3DatagramContextIdRegistration(context_id,
-                                                  &h3_datagram_visitor2);
+  stream_->ReplaceHttp3DatagramVisitor(&h3_datagram_visitor2);
   EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
   session_->OnMessageReceived(
       absl::string_view(datagram.data(), datagram.size()));
-  EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
-              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
-                  stream_->id(), context_id,
-                  std::string(&datagram[1], datagram.size() - 1)}));
+  EXPECT_THAT(
+      h3_datagram_visitor2.received_h3_datagrams(),
+      ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+          stream_->id(), std::string(&datagram[1], datagram.size() - 1)}));
   // Cleanup.
-  stream_->UnregisterHttp3DatagramContextId(context_id);
-  stream_->UnregisterHttp3DatagramRegistrationVisitor();
+  stream_->UnregisterHttp3DatagramVisitor();
   session_->UnregisterHttp3DatagramFlowId(stream_->id());
 }
 
-TEST_P(QuicSpdyStreamTest, H3DatagramRegistrationWithoutContextDraft04) {
+TEST_P(QuicSpdyStreamTest, ReceiveHttpDatagramDraft04) {
   if (!UsesHttp3()) {
     return;
   }
@@ -3283,117 +3240,36 @@
   headers_[":method"] = "CONNECT";
   headers_[":protocol"] = "webtransport";
   ProcessHeaders(false, headers_);
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
-      h3_datagram_registration_visitor;
   SavingHttp3DatagramVisitor h3_datagram_visitor;
-  absl::optional<QuicDatagramContextId> context_id;
-  absl::string_view format_additional_data;
   ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
   std::array<char, 256> datagram;
   datagram[0] = stream_->id();
   for (size_t i = 1; i < datagram.size(); i++) {
     datagram[i] = i;
   }
-  stream_->RegisterHttp3DatagramRegistrationVisitor(
-      &h3_datagram_registration_visitor);
 
-  // Expect us to send a REGISTER_DATAGRAM_NO_CONTEXT capsule.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
-      .Times(AtLeast(1));
-
-  stream_->RegisterHttp3DatagramContextId(
-      context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
-      &h3_datagram_visitor);
+  stream_->RegisterHttp3DatagramVisitor(&h3_datagram_visitor);
   session_->OnMessageReceived(
       absl::string_view(datagram.data(), datagram.size()));
-  EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
-              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
-                  stream_->id(), context_id,
-                  std::string(&datagram[1], datagram.size() - 1)}));
+  EXPECT_THAT(
+      h3_datagram_visitor.received_h3_datagrams(),
+      ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+          stream_->id(), std::string(&datagram[1], datagram.size() - 1)}));
   // Test move.
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
-      h3_datagram_registration_visitor2;
-  stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
   SavingHttp3DatagramVisitor h3_datagram_visitor2;
-  stream_->MoveHttp3DatagramContextIdRegistration(context_id,
-                                                  &h3_datagram_visitor2);
+  stream_->ReplaceHttp3DatagramVisitor(&h3_datagram_visitor2);
   EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
   session_->OnMessageReceived(
       absl::string_view(datagram.data(), datagram.size()));
-  EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
-              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
-                  stream_->id(), context_id,
-                  std::string(&datagram[1], datagram.size() - 1)}));
+  EXPECT_THAT(
+      h3_datagram_visitor2.received_h3_datagrams(),
+      ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+          stream_->id(), std::string(&datagram[1], datagram.size() - 1)}));
   // Cleanup.
-  stream_->UnregisterHttp3DatagramContextId(context_id);
-  stream_->UnregisterHttp3DatagramRegistrationVisitor();
+  stream_->UnregisterHttp3DatagramVisitor();
 }
 
-TEST_P(QuicSpdyStreamTest, HttpDatagramRegistrationWithContext) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft04);
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
-      h3_datagram_registration_visitor;
-  SavingHttp3DatagramVisitor h3_datagram_visitor;
-  absl::optional<QuicDatagramContextId> context_id = 42;
-  absl::string_view format_additional_data;
-  ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
-  std::array<char, 256> datagram;
-  datagram[0] = stream_->id();
-  datagram[1] = context_id.value();
-  for (size_t i = 2; i < datagram.size(); i++) {
-    datagram[i] = i;
-  }
-  stream_->RegisterHttp3DatagramRegistrationVisitor(
-      &h3_datagram_registration_visitor, /*use_datagram_contexts=*/true);
-  headers_[":method"] = "CONNECT";
-  headers_[":protocol"] = "webtransport";
-  headers_["sec-use-datagram-contexts"] = "?1";
-  ProcessHeaders(false, headers_);
-
-  // Expect us to send a REGISTER_DATAGRAM_CONTEXT capsule.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
-      .Times(AtLeast(1));
-
-  stream_->RegisterHttp3DatagramContextId(
-      context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
-      &h3_datagram_visitor);
-  session_->OnMessageReceived(
-      absl::string_view(datagram.data(), datagram.size()));
-  EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
-              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
-                  stream_->id(), context_id,
-                  std::string(&datagram[2], datagram.size() - 2)}));
-  // Test move.
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
-      h3_datagram_registration_visitor2;
-  stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
-  SavingHttp3DatagramVisitor h3_datagram_visitor2;
-  stream_->MoveHttp3DatagramContextIdRegistration(context_id,
-                                                  &h3_datagram_visitor2);
-  EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
-  session_->OnMessageReceived(
-      absl::string_view(datagram.data(), datagram.size()));
-  EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
-              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
-                  stream_->id(), context_id,
-                  std::string(&datagram[2], datagram.size() - 2)}));
-  // Cleanup.
-
-  // Expect us to send a CLOSE_DATAGRAM_CONTEXT capsule.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
-      .Times(AtLeast(1));
-  stream_->UnregisterHttp3DatagramContextId(context_id);
-  stream_->UnregisterHttp3DatagramRegistrationVisitor();
-  session_->UnregisterHttp3DatagramFlowId(stream_->id());
-}
-
-TEST_P(QuicSpdyStreamTest, SendHttp3Datagram) {
+TEST_P(QuicSpdyStreamTest, SendHttpDatagram) {
   if (!UsesHttp3()) {
     return;
   }
@@ -3401,11 +3277,10 @@
   session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
   QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
                                               HttpDatagramSupport::kDraft04);
-  absl::optional<QuicDatagramContextId> context_id;
-  std::string h3_datagram_payload = {1, 2, 3, 4, 5, 6};
+  std::string http_datagram_payload = {1, 2, 3, 4, 5, 6};
   EXPECT_CALL(*connection_, SendMessage(1, _, false))
       .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
-  EXPECT_EQ(stream_->SendHttp3Datagram(context_id, h3_datagram_payload),
+  EXPECT_EQ(stream_->SendHttp3Datagram(http_datagram_payload),
             MESSAGE_STATUS_SUCCESS);
 }
 
@@ -3417,12 +3292,7 @@
   session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
   QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
                                               HttpDatagramSupport::kDraft04);
-
-  QuicByteCount size = stream_->GetMaxDatagramSize(absl::nullopt);
-  QuicByteCount size_with_context =
-      stream_->GetMaxDatagramSize(/*context_id=*/1);
-  EXPECT_GT(size, 512u);
-  EXPECT_EQ(size - 1, size_with_context);
+  EXPECT_GT(stream_->GetMaxDatagramSize(), 512u);
 }
 
 TEST_P(QuicSpdyStreamTest,
diff --git a/quiche/quic/core/http/web_transport_http3.cc b/quiche/quic/core/http/web_transport_http3.cc
index f0e3849..e10e8ad 100644
--- a/quiche/quic/core/http/web_transport_http3.cc
+++ b/quiche/quic/core/http/web_transport_http3.cc
@@ -42,8 +42,7 @@
 
 WebTransportHttp3::WebTransportHttp3(QuicSpdySession* session,
                                      QuicSpdyStream* connect_stream,
-                                     WebTransportSessionId id,
-                                     bool attempt_to_use_datagram_contexts)
+                                     WebTransportSessionId id)
     : session_(session),
       connect_stream_(connect_stream),
       id_(id),
@@ -51,15 +50,7 @@
   QUICHE_DCHECK(session_->SupportsWebTransport());
   QUICHE_DCHECK(IsValidWebTransportSessionId(id, session_->version()));
   QUICHE_DCHECK_EQ(connect_stream_->id(), id);
-  connect_stream_->RegisterHttp3DatagramRegistrationVisitor(
-      this, attempt_to_use_datagram_contexts);
-  if (session_->perspective() == Perspective::IS_CLIENT) {
-    context_is_known_ = true;
-    context_currently_registered_ = true;
-    if (attempt_to_use_datagram_contexts) {
-      context_id_ = connect_stream_->GetNextDatagramContextId();
-    }
-  }
+  connect_stream_->RegisterHttp3DatagramVisitor(this);
 }
 
 void WebTransportHttp3::AssociateStream(QuicStreamId stream_id) {
@@ -87,11 +78,7 @@
   for (QuicStreamId id : streams) {
     session_->ResetStream(id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE);
   }
-  if (context_currently_registered_) {
-    context_currently_registered_ = false;
-    connect_stream_->UnregisterHttp3DatagramContextId(context_id_);
-  }
-  connect_stream_->UnregisterHttp3DatagramRegistrationVisitor();
+  connect_stream_->UnregisterHttp3DatagramVisitor();
 
   MaybeNotifyClose();
 }
@@ -283,11 +270,11 @@
 MessageStatus WebTransportHttp3::SendOrQueueDatagram(
     quiche::QuicheMemSlice datagram) {
   return connect_stream_->SendHttp3Datagram(
-      context_id_, absl::string_view(datagram.data(), datagram.length()));
+      absl::string_view(datagram.data(), datagram.length()));
 }
 
 QuicByteCount WebTransportHttp3::GetMaxDatagramSize() const {
-  return connect_stream_->GetMaxDatagramSize(context_id_);
+  return connect_stream_->GetMaxDatagramSize();
 }
 
 void WebTransportHttp3::SetDatagramMaxTimeInQueue(
@@ -295,88 +282,12 @@
   connect_stream_->SetMaxDatagramTimeInQueue(max_time_in_queue);
 }
 
-void WebTransportHttp3::OnHttp3Datagram(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    absl::string_view payload) {
+void WebTransportHttp3::OnHttp3Datagram(QuicStreamId stream_id,
+                                        absl::string_view payload) {
   QUICHE_DCHECK_EQ(stream_id, connect_stream_->id());
-  QUICHE_DCHECK(context_id == context_id_);
   visitor_->OnDatagramReceived(payload);
 }
 
-void WebTransportHttp3::OnContextReceived(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    DatagramFormatType format_type, absl::string_view format_additional_data) {
-  if (stream_id != connect_stream_->id()) {
-    QUIC_BUG(WT3 bad datagram context registration)
-        << ENDPOINT << "Registered stream ID " << stream_id << ", expected "
-        << connect_stream_->id();
-    return;
-  }
-  if (format_type != DatagramFormatType::WEBTRANSPORT) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected datagram format type "
-                    << DatagramFormatTypeToString(format_type);
-    return;
-  }
-  if (!format_additional_data.empty()) {
-    QUIC_DLOG(ERROR)
-        << ENDPOINT
-        << "Received non-empty format additional data for context ID "
-        << (context_id_.has_value() ? context_id_.value() : 0)
-        << " on stream ID " << connect_stream_->id();
-    session_->ResetStream(connect_stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD);
-    return;
-  }
-  if (!context_is_known_) {
-    context_is_known_ = true;
-    context_id_ = context_id;
-  }
-  if (context_id != context_id_) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected context ID "
-                    << (context_id.has_value() ? context_id.value() : 0)
-                    << " instead of "
-                    << (context_id_.has_value() ? context_id_.value() : 0)
-                    << " on stream ID " << connect_stream_->id();
-    return;
-  }
-  if (session_->perspective() == Perspective::IS_SERVER) {
-    if (context_currently_registered_) {
-      QUIC_DLOG(ERROR) << ENDPOINT << "Received duplicate context ID "
-                       << (context_id_.has_value() ? context_id_.value() : 0)
-                       << " on stream ID " << connect_stream_->id();
-      session_->ResetStream(connect_stream_->id(), QUIC_STREAM_CANCELLED);
-      return;
-    }
-    context_currently_registered_ = true;
-    connect_stream_->RegisterHttp3DatagramContextId(
-        context_id_, format_type, format_additional_data, this);
-  }
-}
-
-void WebTransportHttp3::OnContextClosed(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    ContextCloseCode close_code, absl::string_view close_details) {
-  if (stream_id != connect_stream_->id()) {
-    QUIC_BUG(WT3 bad datagram context registration)
-        << ENDPOINT << "Closed context on stream ID " << stream_id
-        << ", expected " << connect_stream_->id();
-    return;
-  }
-  if (context_id != context_id_) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected close of context ID "
-                    << (context_id.has_value() ? context_id.value() : 0)
-                    << " instead of "
-                    << (context_id_.has_value() ? context_id_.value() : 0)
-                    << " on stream ID " << connect_stream_->id();
-    return;
-  }
-  QUIC_DLOG(INFO) << ENDPOINT
-                  << "Received datagram context close with close code "
-                  << close_code << " close details \"" << close_details
-                  << "\" on stream ID " << connect_stream_->id()
-                  << ", resetting stream";
-  session_->ResetStream(connect_stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD);
-}
-
 void WebTransportHttp3::MaybeNotifyClose() {
   if (close_notified_) {
     return;
diff --git a/quiche/quic/core/http/web_transport_http3.h b/quiche/quic/core/http/web_transport_http3.h
index 03ed764..3924a7d 100644
--- a/quiche/quic/core/http/web_transport_http3.h
+++ b/quiche/quic/core/http/web_transport_http3.h
@@ -39,12 +39,10 @@
 // <https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3>
 class QUIC_EXPORT_PRIVATE WebTransportHttp3
     : public WebTransportSession,
-      public QuicSpdyStream::Http3DatagramRegistrationVisitor,
       public QuicSpdyStream::Http3DatagramVisitor {
  public:
   WebTransportHttp3(QuicSpdySession* session, QuicSpdyStream* connect_stream,
-                    WebTransportSessionId id,
-                    bool attempt_to_use_datagram_contexts);
+                    WebTransportSessionId id);
 
   void HeadersReceived(const spdy::SpdyHeaderBlock& headers);
   void SetVisitor(std::unique_ptr<WebTransportVisitor> visitor) {
@@ -53,9 +51,6 @@
 
   WebTransportSessionId id() { return id_; }
   bool ready() { return ready_; }
-  absl::optional<QuicDatagramContextId> context_id() const {
-    return context_id_;
-  }
 
   void AssociateStream(QuicStreamId stream_id);
   void OnStreamClosed(QuicStreamId stream_id) { streams_.erase(stream_id); }
@@ -91,19 +86,8 @@
 
   // From QuicSpdyStream::Http3DatagramVisitor.
   void OnHttp3Datagram(QuicStreamId stream_id,
-                       absl::optional<QuicDatagramContextId> context_id,
                        absl::string_view payload) override;
 
-  // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
-  void OnContextReceived(QuicStreamId stream_id,
-                         absl::optional<QuicDatagramContextId> context_id,
-                         DatagramFormatType format_type,
-                         absl::string_view format_additional_data) override;
-  void OnContextClosed(QuicStreamId stream_id,
-                       absl::optional<QuicDatagramContextId> context_id,
-                       ContextCloseCode close_code,
-                       absl::string_view close_details) override;
-
   bool close_received() const { return close_received_; }
   WebTransportHttp3RejectionReason rejection_reason() const {
     return rejection_reason_;
@@ -117,15 +101,8 @@
   QuicSpdySession* const session_;        // Unowned.
   QuicSpdyStream* const connect_stream_;  // Unowned.
   const WebTransportSessionId id_;
-  absl::optional<QuicDatagramContextId> context_id_;
   // |ready_| is set to true when the peer has seen both sets of headers.
   bool ready_ = false;
-  // Whether we know which |context_id_| to use. On the client this is always
-  // true, and on the server it becomes true when we receive a context
-  // registration capsule.
-  bool context_is_known_ = false;
-  // Whether |context_id_| is currently registered with |connect_stream_|.
-  bool context_currently_registered_ = false;
   std::unique_ptr<WebTransportVisitor> visitor_;
   absl::flat_hash_set<QuicStreamId> streams_;
   quiche::QuicheCircularDeque<QuicStreamId> incoming_bidirectional_streams_;
diff --git a/quiche/quic/masque/masque_client_session.cc b/quiche/quic/masque/masque_client_session.cc
index fc6da5a..9a69dad 100644
--- a/quiche/quic/masque/masque_client_session.cc
+++ b/quiche/quic/masque/masque_client_session.cc
@@ -168,10 +168,8 @@
     return nullptr;
   }
 
-  absl::optional<QuicDatagramContextId> context_id;
-  connect_udp_client_states_.push_back(
-      ConnectUdpClientState(stream, encapsulated_client_session, this,
-                            context_id, target_server_address));
+  connect_udp_client_states_.push_back(ConnectUdpClientState(
+      stream, encapsulated_client_session, this, target_server_address));
   return &connect_udp_client_states_.back();
 }
 
@@ -193,15 +191,11 @@
     return;
   }
 
-  MessageStatus message_status = SendHttp3Datagram(
-      connect_udp->stream()->id(), connect_udp->context_id(), packet);
+  MessageStatus message_status =
+      SendHttp3Datagram(connect_udp->stream()->id(), packet);
 
   QUIC_DVLOG(1) << "Sent packet to " << target_server_address
                 << " compressed with stream ID " << connect_udp->stream()->id()
-                << " context ID "
-                << (connect_udp->context_id().has_value()
-                        ? absl::StrCat(connect_udp->context_id().value())
-                        : "none")
                 << " and got message status "
                 << MessageStatusToString(message_status);
 }
@@ -237,11 +231,7 @@
   for (auto it = connect_udp_client_states_.begin();
        it != connect_udp_client_states_.end();) {
     if (it->encapsulated_client_session() == encapsulated_client_session) {
-      QUIC_DLOG(INFO) << "Removing state for stream ID " << it->stream()->id()
-                      << " context ID "
-                      << (it->context_id().has_value()
-                              ? absl::StrCat(it->context_id().value())
-                              : "none");
+      QUIC_DLOG(INFO) << "Removing state for stream ID " << it->stream()->id();
       auto* stream = it->stream();
       it = connect_udp_client_states_.erase(it);
       if (!stream->write_side_closed()) {
@@ -279,10 +269,7 @@
        it != connect_udp_client_states_.end();) {
     if (it->stream()->id() == stream_id) {
       QUIC_DLOG(INFO) << "Stream " << stream_id
-                      << " was closed, removing state for context ID "
-                      << (it->context_id().has_value()
-                              ? absl::StrCat(it->context_id().value())
-                              : "none");
+                      << " was closed, removing state";
       auto* encapsulated_client_session = it->encapsulated_client_session();
       it = connect_udp_client_states_.erase(it);
       encapsulated_client_session->CloseConnection(
@@ -316,24 +303,18 @@
     QuicSpdyClientStream* stream,
     EncapsulatedClientSession* encapsulated_client_session,
     MasqueClientSession* masque_session,
-    absl::optional<QuicDatagramContextId> context_id,
     const QuicSocketAddress& target_server_address)
     : stream_(stream),
       encapsulated_client_session_(encapsulated_client_session),
       masque_session_(masque_session),
-      context_id_(context_id),
       target_server_address_(target_server_address) {
   QUICHE_DCHECK_NE(masque_session_, nullptr);
-  this->stream()->RegisterHttp3DatagramRegistrationVisitor(this);
-  this->stream()->RegisterHttp3DatagramContextId(
-      this->context_id(), DatagramFormatType::UDP_PAYLOAD,
-      /*format_additional_data=*/absl::string_view(), this);
+  this->stream()->RegisterHttp3DatagramVisitor(this);
 }
 
 MasqueClientSession::ConnectUdpClientState::~ConnectUdpClientState() {
   if (stream() != nullptr) {
-    stream()->UnregisterHttp3DatagramContextId(context_id());
-    stream()->UnregisterHttp3DatagramRegistrationVisitor();
+    stream()->UnregisterHttp3DatagramVisitor();
   }
 }
 
@@ -348,88 +329,20 @@
   stream_ = other.stream_;
   encapsulated_client_session_ = other.encapsulated_client_session_;
   masque_session_ = other.masque_session_;
-  context_id_ = other.context_id_;
   target_server_address_ = other.target_server_address_;
   other.stream_ = nullptr;
   if (stream() != nullptr) {
-    stream()->MoveHttp3DatagramRegistration(this);
-    stream()->MoveHttp3DatagramContextIdRegistration(context_id(), this);
+    stream()->ReplaceHttp3DatagramVisitor(this);
   }
   return *this;
 }
 
 void MasqueClientSession::ConnectUdpClientState::OnHttp3Datagram(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    absl::string_view payload) {
+    QuicStreamId stream_id, absl::string_view payload) {
   QUICHE_DCHECK_EQ(stream_id, stream()->id());
-  QUICHE_DCHECK(context_id == context_id_);
   encapsulated_client_session_->ProcessPacket(payload, target_server_address_);
   QUIC_DVLOG(1) << "Sent " << payload.size()
-                << " bytes to connection for stream ID " << stream_id
-                << " context ID "
-                << (context_id.has_value() ? absl::StrCat(context_id.value())
-                                           : "none");
-}
-
-void MasqueClientSession::ConnectUdpClientState::OnContextReceived(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    DatagramFormatType format_type, absl::string_view format_additional_data) {
-  if (stream_id != stream_->id()) {
-    QUIC_BUG(MASQUE client bad datagram context registration)
-        << "Registered stream ID " << stream_id << ", expected "
-        << stream_->id();
-    return;
-  }
-  if (format_type != DatagramFormatType::UDP_PAYLOAD) {
-    QUIC_DLOG(INFO) << "Ignoring unexpected datagram format type "
-                    << DatagramFormatTypeToString(format_type);
-    return;
-  }
-  if (!format_additional_data.empty()) {
-    QUIC_DLOG(ERROR)
-        << "Received non-empty format additional data for context ID "
-        << (context_id_.has_value() ? context_id_.value() : 0)
-        << " on stream ID " << stream()->id();
-    masque_session_->ResetStream(stream()->id(), QUIC_STREAM_CANCELLED);
-    return;
-  }
-  if (context_id != context_id_) {
-    QUIC_DLOG(INFO)
-        << "Ignoring unexpected context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " instead of "
-        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
-                                    : "none")
-        << " on stream ID " << stream_->id();
-    return;
-  }
-  // Do nothing since the client registers first and we currently ignore
-  // extensions.
-}
-
-void MasqueClientSession::ConnectUdpClientState::OnContextClosed(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    ContextCloseCode close_code, absl::string_view close_details) {
-  if (stream_id != stream_->id()) {
-    QUIC_BUG(MASQUE client bad datagram context registration)
-        << "Closed context on stream ID " << stream_id << ", expected "
-        << stream_->id();
-    return;
-  }
-  if (context_id != context_id_) {
-    QUIC_DLOG(INFO)
-        << "Ignoring unexpected close of context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " instead of "
-        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
-                                    : "none")
-        << " on stream ID " << stream_->id();
-    return;
-  }
-  QUIC_DLOG(INFO) << "Received datagram context close with close code "
-                  << close_code << " close details \"" << close_details
-                  << "\" on stream ID " << stream_->id() << ", closing stream";
-  masque_session_->ResetStream(stream_->id(), QUIC_STREAM_CANCELLED);
+                << " bytes to connection for stream ID " << stream_id;
 }
 
 }  // namespace quic
diff --git a/quiche/quic/masque/masque_client_session.h b/quiche/quic/masque/masque_client_session.h
index 07673c3..6e469b2 100644
--- a/quiche/quic/masque/masque_client_session.h
+++ b/quiche/quic/masque/masque_client_session.h
@@ -107,8 +107,7 @@
  private:
   // State that the MasqueClientSession keeps for each CONNECT-UDP request.
   class QUIC_NO_EXPORT ConnectUdpClientState
-      : public QuicSpdyStream::Http3DatagramRegistrationVisitor,
-        public QuicSpdyStream::Http3DatagramVisitor {
+      : public QuicSpdyStream::Http3DatagramVisitor {
    public:
     // |stream| and |encapsulated_client_session| must be valid for the lifetime
     // of the ConnectUdpClientState.
@@ -116,7 +115,6 @@
         QuicSpdyClientStream* stream,
         EncapsulatedClientSession* encapsulated_client_session,
         MasqueClientSession* masque_session,
-        absl::optional<QuicDatagramContextId> context_id,
         const QuicSocketAddress& target_server_address);
 
     ~ConnectUdpClientState();
@@ -131,33 +129,18 @@
     EncapsulatedClientSession* encapsulated_client_session() const {
       return encapsulated_client_session_;
     }
-    absl::optional<QuicDatagramContextId> context_id() const {
-      return context_id_;
-    }
     const QuicSocketAddress& target_server_address() const {
       return target_server_address_;
     }
 
     // From QuicSpdyStream::Http3DatagramVisitor.
     void OnHttp3Datagram(QuicStreamId stream_id,
-                         absl::optional<QuicDatagramContextId> context_id,
                          absl::string_view payload) override;
 
-    // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
-    void OnContextReceived(QuicStreamId stream_id,
-                           absl::optional<QuicDatagramContextId> context_id,
-                           DatagramFormatType format_type,
-                           absl::string_view format_additional_data) override;
-    void OnContextClosed(QuicStreamId stream_id,
-                         absl::optional<QuicDatagramContextId> context_id,
-                         ContextCloseCode close_code,
-                         absl::string_view close_details) override;
-
    private:
     QuicSpdyClientStream* stream_;                            // Unowned.
     EncapsulatedClientSession* encapsulated_client_session_;  // Unowned.
     MasqueClientSession* masque_session_;                     // Unowned.
-    absl::optional<QuicDatagramContextId> context_id_;
     QuicSocketAddress target_server_address_;
   };
 
diff --git a/quiche/quic/masque/masque_server_session.cc b/quiche/quic/masque/masque_server_session.cc
index f221094..268421f 100644
--- a/quiche/quic/masque/masque_server_session.cc
+++ b/quiche/quic/masque/masque_server_session.cc
@@ -286,7 +286,6 @@
     }
     epoll_server_->RegisterFDForRead(fd_wrapper.fd(), this);
 
-    absl::optional<QuicDatagramContextId> context_id;
     QuicSpdyStream* stream = static_cast<QuicSpdyStream*>(
         GetActiveStream(request_handler->stream_id()));
     if (stream == nullptr) {
@@ -298,17 +297,13 @@
     if (flow_id.has_value()) {
       stream->RegisterHttp3DatagramFlowId(*flow_id);
     }
-    connect_udp_server_states_.push_back(
-        ConnectUdpServerState(stream, context_id, target_server_address,
-                              fd_wrapper.extract_fd(), this));
+    connect_udp_server_states_.push_back(ConnectUdpServerState(
+        stream, target_server_address, fd_wrapper.extract_fd(), this));
 
     if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
       // TODO(b/181256914) remove this when we drop support for
       // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
-      stream->RegisterHttp3DatagramContextId(
-          context_id, DatagramFormatType::UDP_PAYLOAD,
-          /*format_additional_data=*/absl::string_view(),
-          &connect_udp_server_states_.back());
+      stream->RegisterHttp3DatagramVisitor(&connect_udp_server_states_.back());
     }
 
     spdy::Http2HeaderBlock response_headers;
@@ -437,7 +432,6 @@
     }
     // The packet is valid, send it to the client in a DATAGRAM frame.
     MessageStatus message_status = it->stream()->SendHttp3Datagram(
-        it->context_id(),
         absl::string_view(read_result.packet_buffer.buffer,
                           read_result.packet_buffer.buffer_len));
     QUIC_DVLOG(1) << "Sent UDP packet from " << expected_target_server_address
@@ -476,25 +470,20 @@
 }
 
 MasqueServerSession::ConnectUdpServerState::ConnectUdpServerState(
-    QuicSpdyStream* stream, absl::optional<QuicDatagramContextId> context_id,
-    const QuicSocketAddress& target_server_address, QuicUdpSocketFd fd,
-    MasqueServerSession* masque_session)
+    QuicSpdyStream* stream, const QuicSocketAddress& target_server_address,
+    QuicUdpSocketFd fd, MasqueServerSession* masque_session)
     : stream_(stream),
-      context_id_(context_id),
       target_server_address_(target_server_address),
       fd_(fd),
       masque_session_(masque_session) {
   QUICHE_DCHECK_NE(fd_, kQuicInvalidSocketFd);
   QUICHE_DCHECK_NE(masque_session_, nullptr);
-  this->stream()->RegisterHttp3DatagramRegistrationVisitor(this);
+  this->stream()->RegisterHttp3DatagramVisitor(this);
 }
 
 MasqueServerSession::ConnectUdpServerState::~ConnectUdpServerState() {
   if (stream() != nullptr) {
-    if (context_registered_) {
-      stream()->UnregisterHttp3DatagramContextId(context_id());
-    }
-    stream()->UnregisterHttp3DatagramRegistrationVisitor();
+    stream()->UnregisterHttp3DatagramVisitor();
   }
   if (fd_ == kQuicInvalidSocketFd) {
     return;
@@ -522,27 +511,19 @@
   }
   stream_ = other.stream_;
   other.stream_ = nullptr;
-  context_id_ = other.context_id_;
   target_server_address_ = other.target_server_address_;
   fd_ = other.fd_;
   masque_session_ = other.masque_session_;
   other.fd_ = kQuicInvalidSocketFd;
-  context_registered_ = other.context_registered_;
-  other.context_registered_ = false;
   if (stream() != nullptr) {
-    stream()->MoveHttp3DatagramRegistration(this);
-    if (context_registered_) {
-      stream()->MoveHttp3DatagramContextIdRegistration(context_id(), this);
-    }
+    stream()->ReplaceHttp3DatagramVisitor(this);
   }
   return *this;
 }
 
 void MasqueServerSession::ConnectUdpServerState::OnHttp3Datagram(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    absl::string_view payload) {
+    QuicStreamId stream_id, absl::string_view payload) {
   QUICHE_DCHECK_EQ(stream_id, stream()->id());
-  QUICHE_DCHECK(context_id == context_id_);
   QuicUdpSocketApi socket_api;
   QuicUdpPacketInfo packet_info;
   packet_info.SetPeerAddress(target_server_address_);
@@ -552,77 +533,4 @@
                 << target_server_address_ << " with result " << write_result;
 }
 
-void MasqueServerSession::ConnectUdpServerState::OnContextReceived(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    DatagramFormatType format_type, absl::string_view format_additional_data) {
-  if (stream_id != stream()->id()) {
-    QUIC_BUG(MASQUE server bad datagram context registration)
-        << "Registered stream ID " << stream_id << ", expected "
-        << stream()->id();
-    return;
-  }
-  if (format_type != DatagramFormatType::UDP_PAYLOAD) {
-    QUIC_DLOG(INFO) << "Ignoring unexpected datagram format type "
-                    << DatagramFormatTypeToString(format_type);
-    return;
-  }
-  if (!format_additional_data.empty()) {
-    QUIC_DLOG(ERROR)
-        << "Received non-empty format additional data for context ID "
-        << (context_id_.has_value() ? context_id_.value() : 0)
-        << " on stream ID " << stream()->id();
-    masque_session_->ResetStream(stream()->id(), QUIC_STREAM_CANCELLED);
-    return;
-  }
-  if (!context_received_) {
-    context_received_ = true;
-    context_id_ = context_id;
-  }
-  if (context_id != context_id_) {
-    QUIC_DLOG(INFO)
-        << "Ignoring unexpected context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " instead of "
-        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
-                                    : "none")
-        << " on stream ID " << stream()->id();
-    return;
-  }
-  if (context_registered_) {
-    QUIC_BUG(MASQUE server double datagram context registration)
-        << "Try to re-register stream ID " << stream_id << " context ID "
-        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
-                                    : "none");
-    return;
-  }
-  context_registered_ = true;
-  stream()->RegisterHttp3DatagramContextId(context_id_, format_type,
-                                           format_additional_data, this);
-}
-
-void MasqueServerSession::ConnectUdpServerState::OnContextClosed(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    ContextCloseCode close_code, absl::string_view close_details) {
-  if (stream_id != stream()->id()) {
-    QUIC_BUG(MASQUE server bad datagram context registration)
-        << "Closed context on stream ID " << stream_id << ", expected "
-        << stream()->id();
-    return;
-  }
-  if (context_id != context_id_) {
-    QUIC_DLOG(INFO)
-        << "Ignoring unexpected close of context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " instead of "
-        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
-                                    : "none")
-        << " on stream ID " << stream()->id();
-    return;
-  }
-  QUIC_DLOG(INFO) << "Received datagram context close with close code "
-                  << close_code << " close details \"" << close_details
-                  << "\" on stream ID " << stream()->id() << ", closing stream";
-  masque_session_->ResetStream(stream()->id(), QUIC_STREAM_CANCELLED);
-}
-
 }  // namespace quic
diff --git a/quiche/quic/masque/masque_server_session.h b/quiche/quic/masque/masque_server_session.h
index 746779e..09aedb9 100644
--- a/quiche/quic/masque/masque_server_session.h
+++ b/quiche/quic/masque/masque_server_session.h
@@ -83,14 +83,12 @@
  private:
   // State that the MasqueServerSession keeps for each CONNECT-UDP request.
   class QUIC_NO_EXPORT ConnectUdpServerState
-      : public QuicSpdyStream::Http3DatagramRegistrationVisitor,
-        public QuicSpdyStream::Http3DatagramVisitor {
+      : public QuicSpdyStream::Http3DatagramVisitor {
    public:
     // ConnectUdpServerState takes ownership of |fd|. It will unregister it
     // from |epoll_server| and close the file descriptor when destructed.
     explicit ConnectUdpServerState(
         QuicSpdyStream* stream,
-        absl::optional<QuicDatagramContextId> context_id,
         const QuicSocketAddress& target_server_address, QuicUdpSocketFd fd,
         MasqueServerSession* masque_session);
 
@@ -103,9 +101,6 @@
     ConnectUdpServerState& operator=(ConnectUdpServerState&&);
 
     QuicSpdyStream* stream() const { return stream_; }
-    absl::optional<QuicDatagramContextId> context_id() const {
-      return context_id_;
-    }
     const QuicSocketAddress& target_server_address() const {
       return target_server_address_;
     }
@@ -113,27 +108,13 @@
 
     // From QuicSpdyStream::Http3DatagramVisitor.
     void OnHttp3Datagram(QuicStreamId stream_id,
-                         absl::optional<QuicDatagramContextId> context_id,
                          absl::string_view payload) override;
 
-    // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
-    void OnContextReceived(QuicStreamId stream_id,
-                           absl::optional<QuicDatagramContextId> context_id,
-                           DatagramFormatType format_type,
-                           absl::string_view format_additional_data) override;
-    void OnContextClosed(QuicStreamId stream_id,
-                         absl::optional<QuicDatagramContextId> context_id,
-                         ContextCloseCode close_code,
-                         absl::string_view close_details) override;
-
    private:
     QuicSpdyStream* stream_;
-    absl::optional<QuicDatagramContextId> context_id_;
     QuicSocketAddress target_server_address_;
     QuicUdpSocketFd fd_;                   // Owned.
     MasqueServerSession* masque_session_;  // Unowned.
-    bool context_received_ = false;
-    bool context_registered_ = false;
   };
 
   // From QuicSpdySession.
diff --git a/quiche/quic/test_tools/quic_spdy_stream_peer.cc b/quiche/quic/test_tools/quic_spdy_stream_peer.cc
index d2ec5fd..15806b3 100644
--- a/quiche/quic/test_tools/quic_spdy_stream_peer.cc
+++ b/quiche/quic/test_tools/quic_spdy_stream_peer.cc
@@ -25,11 +25,6 @@
 }
 
 // static
-bool QuicSpdyStreamPeer::use_datagram_contexts(QuicSpdyStream* stream) {
-  return stream->use_datagram_contexts_;
-}
-
-// static
 bool QuicSpdyStreamPeer::OnHeadersFrameEnd(QuicSpdyStream* stream) {
   return stream->OnHeadersFrameEnd();
 }
diff --git a/quiche/quic/test_tools/quic_spdy_stream_peer.h b/quiche/quic/test_tools/quic_spdy_stream_peer.h
index e92f89e..40337f9 100644
--- a/quiche/quic/test_tools/quic_spdy_stream_peer.h
+++ b/quiche/quic/test_tools/quic_spdy_stream_peer.h
@@ -24,7 +24,6 @@
           ack_listener);
   static const QuicIntervalSet<QuicStreamOffset>& unacked_frame_headers_offsets(
       QuicSpdyStream* stream);
-  static bool use_datagram_contexts(QuicSpdyStream* stream);
   static bool OnHeadersFrameEnd(QuicSpdyStream* stream);
 };
 
diff --git a/quiche/quic/test_tools/quic_test_backend.h b/quiche/quic/test_tools/quic_test_backend.h
index 8fef41a..33549cc 100644
--- a/quiche/quic/test_tools/quic_test_backend.h
+++ b/quiche/quic/test_tools/quic_test_backend.h
@@ -26,12 +26,6 @@
     enable_webtransport_ = enable_webtransport;
   }
 
-  bool UsesDatagramContexts() override { return use_datagram_contexts_; }
-
-  void set_use_datagram_contexts(bool use_datagram_contexts) {
-    use_datagram_contexts_ = use_datagram_contexts;
-  }
-
   bool SupportsExtendedConnect() override { return enable_extended_connect_; }
 
   void set_enable_extended_connect(bool enable_extended_connect) {
@@ -40,7 +34,6 @@
 
  private:
   bool enable_webtransport_ = false;
-  bool use_datagram_contexts_ = false;
   bool enable_extended_connect_ = true;
 };
 
diff --git a/quiche/quic/test_tools/quic_test_utils.h b/quiche/quic/test_tools/quic_test_utils.h
index a26349b..aadf96f 100644
--- a/quiche/quic/test_tools/quic_test_utils.h
+++ b/quiche/quic/test_tools/quic_test_utils.h
@@ -1987,11 +1987,9 @@
  public:
   struct SavedHttp3Datagram {
     QuicStreamId stream_id;
-    absl::optional<QuicDatagramContextId> context_id;
     std::string payload;
     bool operator==(const SavedHttp3Datagram& o) const {
-      return stream_id == o.stream_id && context_id == o.context_id &&
-             payload == o.payload;
+      return stream_id == o.stream_id && payload == o.payload;
     }
   };
   const std::vector<SavedHttp3Datagram>& received_h3_datagrams() const {
@@ -2000,33 +1998,15 @@
 
   // Override from QuicSpdyStream::Http3DatagramVisitor.
   void OnHttp3Datagram(QuicStreamId stream_id,
-                       absl::optional<QuicDatagramContextId> context_id,
                        absl::string_view payload) override {
     received_h3_datagrams_.push_back(
-        SavedHttp3Datagram{stream_id, context_id, std::string(payload)});
+        SavedHttp3Datagram{stream_id, std::string(payload)});
   }
 
  private:
   std::vector<SavedHttp3Datagram> received_h3_datagrams_;
 };
 
-class MockHttp3DatagramRegistrationVisitor
-    : public QuicSpdyStream::Http3DatagramRegistrationVisitor {
- public:
-  MOCK_METHOD(void, OnContextReceived,
-              (QuicStreamId stream_id,
-               absl::optional<QuicDatagramContextId> context_id,
-               DatagramFormatType format_type,
-               absl::string_view format_additional_data),
-              (override));
-
-  MOCK_METHOD(void, OnContextClosed,
-              (QuicStreamId stream_id,
-               absl::optional<QuicDatagramContextId> context_id,
-               ContextCloseCode close_code, absl::string_view close_details),
-              (override));
-};
-
 }  // namespace test
 }  // namespace quic
 
diff --git a/quiche/quic/tools/quic_client.cc b/quiche/quic/tools/quic_client.cc
index b024ac6..b3e4705 100644
--- a/quiche/quic/tools/quic_client.cc
+++ b/quiche/quic/tools/quic_client.cc
@@ -130,8 +130,7 @@
     QuicConnection* connection) {
   return std::make_unique<QuicSimpleClientSession>(
       *config(), supported_versions, connection, server_id(), crypto_config(),
-      push_promise_index(), drop_response_body(), enable_web_transport(),
-      use_datagram_contexts());
+      push_promise_index(), drop_response_body(), enable_web_transport());
 }
 
 QuicClientEpollNetworkHelper* QuicClient::epoll_network_helper() {
diff --git a/quiche/quic/tools/quic_simple_client_session.cc b/quiche/quic/tools/quic_simple_client_session.cc
index fa211ac..1a001fb 100644
--- a/quiche/quic/tools/quic_simple_client_session.cc
+++ b/quiche/quic/tools/quic_simple_client_session.cc
@@ -16,20 +16,18 @@
     : QuicSimpleClientSession(config, supported_versions, connection, server_id,
                               crypto_config, push_promise_index,
                               drop_response_body,
-                              /*enable_web_transport=*/false,
-                              /*use_datagram_contexts=*/false) {}
+                              /*enable_web_transport=*/false) {}
 
 QuicSimpleClientSession::QuicSimpleClientSession(
     const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
     QuicConnection* connection, const QuicServerId& server_id,
     QuicCryptoClientConfig* crypto_config,
     QuicClientPushPromiseIndex* push_promise_index, bool drop_response_body,
-    bool enable_web_transport, bool use_datagram_contexts)
+    bool enable_web_transport)
     : QuicSpdyClientSession(config, supported_versions, connection, server_id,
                             crypto_config, push_promise_index),
       drop_response_body_(drop_response_body),
-      enable_web_transport_(enable_web_transport),
-      use_datagram_contexts_(use_datagram_contexts) {}
+      enable_web_transport_(enable_web_transport) {}
 
 std::unique_ptr<QuicSpdyClientStream>
 QuicSimpleClientSession::CreateClientStream() {
@@ -42,10 +40,6 @@
   return enable_web_transport_;
 }
 
-bool QuicSimpleClientSession::ShouldNegotiateDatagramContexts() {
-  return use_datagram_contexts_;
-}
-
 HttpDatagramSupport QuicSimpleClientSession::LocalHttpDatagramSupport() {
   return enable_web_transport_ ? HttpDatagramSupport::kDraft04
                                : HttpDatagramSupport::kNone;
diff --git a/quiche/quic/tools/quic_simple_client_session.h b/quiche/quic/tools/quic_simple_client_session.h
index 75ed195..6b6f4a7 100644
--- a/quiche/quic/tools/quic_simple_client_session.h
+++ b/quiche/quic/tools/quic_simple_client_session.h
@@ -25,18 +25,15 @@
                           const QuicServerId& server_id,
                           QuicCryptoClientConfig* crypto_config,
                           QuicClientPushPromiseIndex* push_promise_index,
-                          bool drop_response_body, bool enable_web_transport,
-                          bool use_datagram_contexts);
+                          bool drop_response_body, bool enable_web_transport);
 
   std::unique_ptr<QuicSpdyClientStream> CreateClientStream() override;
   bool ShouldNegotiateWebTransport() override;
-  bool ShouldNegotiateDatagramContexts() override;
   HttpDatagramSupport LocalHttpDatagramSupport() override;
 
  private:
   const bool drop_response_body_;
   const bool enable_web_transport_;
-  const bool use_datagram_contexts_;
 };
 
 }  // namespace quic
diff --git a/quiche/quic/tools/quic_simple_server_backend.h b/quiche/quic/tools/quic_simple_server_backend.h
index f976e72..cfeb8b7 100644
--- a/quiche/quic/tools/quic_simple_server_backend.h
+++ b/quiche/quic/tools/quic_simple_server_backend.h
@@ -66,7 +66,6 @@
     return response;
   }
   virtual bool SupportsWebTransport() { return false; }
-  virtual bool UsesDatagramContexts() { return false; }
   virtual bool SupportsExtendedConnect() { return true; }
 };
 
diff --git a/quiche/quic/tools/quic_simple_server_session.h b/quiche/quic/tools/quic_simple_server_session.h
index 872a457..164f286 100644
--- a/quiche/quic/tools/quic_simple_server_session.h
+++ b/quiche/quic/tools/quic_simple_server_session.h
@@ -70,10 +70,6 @@
 
   void OnCanCreateNewOutgoingStream(bool unidirectional) override;
 
-  bool ShouldNegotiateDatagramContexts() override {
-    return quic_simple_server_backend_->UsesDatagramContexts();
-  }
-
  protected:
   // QuicSession methods:
   QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override;