Drop support for draft-ietf-masque-h3-datagram-00

This was initially used by WebTransport but was deprecated from there before WebTransport shipped. Since then it's been used in MASQUE but that has now also moved on to later drafts. Therefore we are no longer using draft-ietf-masque-h3-datagram-00 anywhere so it can be fuly removed. HTTP Datagrams are not used in any of our production servers so we can modify this code without flag protection.

PiperOrigin-RevId: 448327545
diff --git a/quiche/quic/core/http/capsule.cc b/quiche/quic/core/http/capsule.cc
index ebebbe2..3fba85e 100644
--- a/quiche/quic/core/http/capsule.cc
+++ b/quiche/quic/core/http/capsule.cc
@@ -68,10 +68,8 @@
 
 // static
 Capsule Capsule::LegacyDatagram(
-    absl::optional<QuicDatagramContextId> context_id,
     absl::string_view http_datagram_payload) {
   Capsule capsule(CapsuleType::LEGACY_DATAGRAM);
-  capsule.legacy_datagram_capsule().context_id = context_id;
   capsule.legacy_datagram_capsule().http_datagram_payload =
       http_datagram_payload;
   return capsule;
@@ -134,10 +132,8 @@
   }
   switch (capsule_type_) {
     case CapsuleType::LEGACY_DATAGRAM:
-      return legacy_datagram_capsule_.context_id ==
-                 other.legacy_datagram_capsule_.context_id &&
-             legacy_datagram_capsule_.http_datagram_payload ==
-                 other.legacy_datagram_capsule_.http_datagram_payload;
+      return legacy_datagram_capsule_.http_datagram_payload ==
+             other.legacy_datagram_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;
@@ -155,10 +151,6 @@
   std::string rv = CapsuleTypeToString(capsule_type_);
   switch (capsule_type_) {
     case CapsuleType::LEGACY_DATAGRAM:
-      if (legacy_datagram_capsule_.context_id.has_value()) {
-        absl::StrAppend(&rv, "(", legacy_datagram_capsule_.context_id.value(),
-                        ")");
-      }
       absl::StrAppend(&rv, "[",
                       absl::BytesToHexString(
                           legacy_datagram_capsule_.http_datagram_payload),
@@ -203,10 +195,6 @@
     case CapsuleType::LEGACY_DATAGRAM:
       capsule_data_length =
           capsule.legacy_datagram_capsule().http_datagram_payload.length();
-      if (capsule.legacy_datagram_capsule().context_id.has_value()) {
-        capsule_data_length += QuicDataWriter::GetVarInt62Len(
-            capsule.legacy_datagram_capsule().context_id.value());
-      }
       break;
     case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
       capsule_data_length = capsule.datagram_without_context_capsule()
@@ -237,14 +225,6 @@
   }
   switch (capsule.capsule_type()) {
     case CapsuleType::LEGACY_DATAGRAM:
-      if (capsule.legacy_datagram_capsule().context_id.has_value()) {
-        if (!writer.WriteVarInt62(
-                capsule.legacy_datagram_capsule().context_id.value())) {
-          QUIC_BUG(datagram capsule context ID write fail)
-              << "Failed to write LEGACY_DATAGRAM CAPSULE context ID";
-          return {};
-        }
-      }
       if (!writer.WriteStringPiece(
               capsule.legacy_datagram_capsule().http_datagram_payload)) {
         QUIC_BUG(datagram capsule payload write fail)
diff --git a/quiche/quic/core/http/capsule.h b/quiche/quic/core/http/capsule.h
index 7f99b70..7b4cc46 100644
--- a/quiche/quic/core/http/capsule.h
+++ b/quiche/quic/core/http/capsule.h
@@ -31,7 +31,6 @@
                                              const CapsuleType& capsule_type);
 
 struct QUIC_EXPORT_PRIVATE LegacyDatagramCapsule {
-  absl::optional<QuicDatagramContextId> context_id;
   absl::string_view http_datagram_payload;
 };
 struct QUIC_EXPORT_PRIVATE DatagramWithoutContextCapsule {
@@ -50,7 +49,6 @@
 class QUIC_EXPORT_PRIVATE Capsule {
  public:
   static Capsule LegacyDatagram(
-      absl::optional<QuicDatagramContextId> context_id = absl::nullopt,
       absl::string_view http_datagram_payload = absl::string_view());
   static Capsule DatagramWithoutContext(
       absl::string_view http_datagram_payload = absl::string_view());
diff --git a/quiche/quic/core/http/capsule_test.cc b/quiche/quic/core/http/capsule_test.cc
index 4dd220e..1791bb6 100644
--- a/quiche/quic/core/http/capsule_test.cc
+++ b/quiche/quic/core/http/capsule_test.cc
@@ -74,8 +74,7 @@
       "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
   );
   std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
-  Capsule expected_capsule =
-      Capsule::LegacyDatagram(/*context_id=*/absl::nullopt, datagram_payload);
+  Capsule expected_capsule = Capsule::LegacyDatagram(datagram_payload);
   {
     EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
     ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
diff --git a/quiche/quic/core/http/http_constants.cc b/quiche/quic/core/http/http_constants.cc
index 39d9f5e..03dea06 100644
--- a/quiche/quic/core/http/http_constants.cc
+++ b/quiche/quic/core/http/http_constants.cc
@@ -17,7 +17,6 @@
     RETURN_STRING_LITERAL(SETTINGS_QPACK_MAX_TABLE_CAPACITY);
     RETURN_STRING_LITERAL(SETTINGS_MAX_FIELD_SECTION_SIZE);
     RETURN_STRING_LITERAL(SETTINGS_QPACK_BLOCKED_STREAMS);
-    RETURN_STRING_LITERAL(SETTINGS_H3_DATAGRAM_DRAFT00);
     RETURN_STRING_LITERAL(SETTINGS_H3_DATAGRAM_DRAFT04);
     RETURN_STRING_LITERAL(SETTINGS_WEBTRANS_DRAFT00);
     RETURN_STRING_LITERAL(SETTINGS_ENABLE_CONNECT_PROTOCOL);
diff --git a/quiche/quic/core/http/http_constants.h b/quiche/quic/core/http/http_constants.h
index 097b2a3..ee0a3f3 100644
--- a/quiche/quic/core/http/http_constants.h
+++ b/quiche/quic/core/http/http_constants.h
@@ -38,8 +38,6 @@
   // Same value as spdy::SETTINGS_MAX_HEADER_LIST_SIZE.
   SETTINGS_MAX_FIELD_SECTION_SIZE = 0x06,
   SETTINGS_QPACK_BLOCKED_STREAMS = 0x07,
-  // draft-ietf-masque-h3-datagram-00.
-  SETTINGS_H3_DATAGRAM_DRAFT00 = 0x276,
   // draft-ietf-masque-h3-datagram-04.
   SETTINGS_H3_DATAGRAM_DRAFT04 = 0xffd277,
   // draft-ietf-webtrans-http3-00
diff --git a/quiche/quic/core/http/quic_send_control_stream_test.cc b/quiche/quic/core/http/quic_send_control_stream_test.cc
index aa7606f..f146cee 100644
--- a/quiche/quic/core/http/quic_send_control_stream_test.cc
+++ b/quiche/quic/core/http/quic_send_control_stream_test.cc
@@ -133,11 +133,11 @@
   if ((!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
        perspective() == Perspective::IS_CLIENT) &&
       QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) ==
-          HttpDatagramSupport::kDraft00And04) {
+          HttpDatagramSupport::kDraft04) {
     expected_write_data = absl::HexStringToBytes(
         "00"         // stream type: control stream
         "04"         // frame type: SETTINGS frame
-        "0e"         // frame length
+        "0b"         // frame length
         "01"         // SETTINGS_QPACK_MAX_TABLE_CAPACITY
         "40ff"       // 255
         "06"         // SETTINGS_MAX_HEADER_LIST_SIZE
@@ -146,8 +146,6 @@
         "10"         // 16
         "4040"       // 0x40 as the reserved settings id
         "14"         // 20
-        "4276"       // SETTINGS_H3_DATAGRAM_DRAFT00
-        "01"         // 1
         "800ffd277"  // SETTINGS_H3_DATAGRAM_DRAFT04
         "01"         // 1
         "4040"       // 0x40 as the reserved frame type
@@ -183,7 +181,7 @@
     expected_write_data = absl::HexStringToBytes(
         "00"         // stream type: control stream
         "04"         // frame type: SETTINGS frame
-        "11"         // frame length
+        "0e"         // frame length
         "01"         // SETTINGS_QPACK_MAX_TABLE_CAPACITY
         "40ff"       // 255
         "06"         // SETTINGS_MAX_HEADER_LIST_SIZE
@@ -194,8 +192,6 @@
         "01"         // 1
         "4040"       // 0x40 as the reserved settings id
         "14"         // 20
-        "4276"       // SETTINGS_H3_DATAGRAM_DRAFT00
-        "01"         // 1
         "800ffd277"  // SETTINGS_H3_DATAGRAM_DRAFT04
         "01"         // 1
         "4040"       // 0x40 as the reserved frame type
diff --git a/quiche/quic/core/http/quic_spdy_session.cc b/quiche/quic/core/http/quic_spdy_session.cc
index 7c1de92..12efa66 100644
--- a/quiche/quic/core/http/quic_spdy_session.cc
+++ b/quiche/quic/core/http/quic_spdy_session.cc
@@ -518,12 +518,7 @@
   if (version().UsesHttp3()) {
     HttpDatagramSupport local_http_datagram_support =
         LocalHttpDatagramSupport();
-    if (local_http_datagram_support == HttpDatagramSupport::kDraft00 ||
-        local_http_datagram_support == HttpDatagramSupport::kDraft00And04) {
-      settings_.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
-    }
-    if (local_http_datagram_support == HttpDatagramSupport::kDraft04 ||
-        local_http_datagram_support == HttpDatagramSupport::kDraft00And04) {
+    if (local_http_datagram_support == HttpDatagramSupport::kDraft04) {
       settings_.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
     }
   }
@@ -1141,33 +1136,10 @@
             absl::StrCat("received HTTP/2 specific setting in HTTP/3 session: ",
                          id));
         return false;
-      case SETTINGS_H3_DATAGRAM_DRAFT00: {
-        HttpDatagramSupport local_http_datagram_support =
-            LocalHttpDatagramSupport();
-        if (local_http_datagram_support != HttpDatagramSupport::kDraft00 &&
-            local_http_datagram_support != HttpDatagramSupport::kDraft00And04) {
-          break;
-        }
-        QUIC_DVLOG(1) << ENDPOINT
-                      << "SETTINGS_H3_DATAGRAM_DRAFT00 received with value "
-                      << value;
-        if (!version().UsesHttp3()) {
-          break;
-        }
-        if (!VerifySettingIsZeroOrOne(id, value)) {
-          return false;
-        }
-        if (value && http_datagram_support_ != HttpDatagramSupport::kDraft04) {
-          // If both draft-00 and draft-04 are supported, use draft-04.
-          http_datagram_support_ = HttpDatagramSupport::kDraft00;
-        }
-        break;
-      }
       case SETTINGS_H3_DATAGRAM_DRAFT04: {
         HttpDatagramSupport local_http_datagram_support =
             LocalHttpDatagramSupport();
-        if (local_http_datagram_support != HttpDatagramSupport::kDraft04 &&
-            local_http_datagram_support != HttpDatagramSupport::kDraft00And04) {
+        if (local_http_datagram_support != HttpDatagramSupport::kDraft04) {
           break;
         }
         QUIC_DVLOG(1) << ENDPOINT
@@ -1599,18 +1571,15 @@
   }
 }
 
-MessageStatus QuicSpdySession::SendHttp3Datagram(QuicDatagramStreamId stream_id,
+MessageStatus QuicSpdySession::SendHttp3Datagram(QuicStreamId stream_id,
                                                  absl::string_view payload) {
   if (!SupportsH3Datagram()) {
     QUIC_BUG(send http datagram too early)
         << "Refusing to send HTTP Datagram before SETTINGS received";
     return MESSAGE_STATUS_INTERNAL_ERROR;
   }
-  uint64_t stream_id_to_write = stream_id;
-  if (http_datagram_support_ != HttpDatagramSupport::kDraft00) {
-    // Stream ID is sent divided by four as per the specification.
-    stream_id_to_write /= kHttpDatagramStreamIdDivisor;
-  }
+  // Stream ID is sent divided by four as per the specification.
+  uint64_t stream_id_to_write = stream_id / kHttpDatagramStreamIdDivisor;
   size_t slice_length =
       QuicDataWriter::GetVarInt62Len(stream_id_to_write) + payload.length();
   quiche::QuicheBuffer buffer(
@@ -1638,16 +1607,6 @@
   datagram_queue()->SetMaxTimeInQueue(max_time_in_queue);
 }
 
-void QuicSpdySession::RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id,
-                                                  QuicStreamId stream_id) {
-  h3_datagram_flow_id_to_stream_id_map_[flow_id] = stream_id;
-}
-
-void QuicSpdySession::UnregisterHttp3DatagramFlowId(
-    QuicDatagramStreamId flow_id) {
-  h3_datagram_flow_id_to_stream_id_map_.erase(flow_id);
-}
-
 void QuicSpdySession::OnMessageReceived(absl::string_view message) {
   QuicSession::OnMessageReceived(message);
   if (!SupportsH3Datagram()) {
@@ -1660,35 +1619,24 @@
     QUIC_DLOG(ERROR) << "Failed to parse stream ID in received HTTP/3 datagram";
     return;
   }
-  if (http_datagram_support_ != HttpDatagramSupport::kDraft00) {
-    // Stream ID is sent divided by four as per the specification.
-    stream_id64 *= kHttpDatagramStreamIdDivisor;
-  }
-  if (perspective() == Perspective::IS_SERVER &&
-      http_datagram_support_ == HttpDatagramSupport::kDraft00) {
-    auto it = h3_datagram_flow_id_to_stream_id_map_.find(stream_id64);
-    if (it == h3_datagram_flow_id_to_stream_id_map_.end()) {
-      QUIC_DLOG(INFO) << "Received unknown HTTP/3 datagram flow ID "
-                      << stream_id64;
-      return;
-    }
-    stream_id64 = it->second;
-  }
-  if (stream_id64 > std::numeric_limits<QuicStreamId>::max()) {
-    // TODO(b/181256914) make this a connection close once we deprecate
-    // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
-    QUIC_DLOG(ERROR) << "Received unexpectedly high HTTP/3 datagram stream ID "
-                     << stream_id64;
+  // Stream ID is sent divided by four as per the specification.
+  if (stream_id64 >
+      std::numeric_limits<QuicStreamId>::max() / kHttpDatagramStreamIdDivisor) {
+    CloseConnectionWithDetails(
+        QUIC_HTTP_FRAME_ERROR,
+        absl::StrCat("Received HTTP Datagram with invalid quarter stream ID ",
+                     stream_id64));
     return;
   }
+  stream_id64 *= kHttpDatagramStreamIdDivisor;
   QuicStreamId stream_id = static_cast<QuicStreamId>(stream_id64);
   QuicSpdyStream* stream =
       static_cast<QuicSpdyStream*>(GetActiveStream(stream_id));
   if (stream == nullptr) {
     QUIC_DLOG(INFO) << "Received HTTP/3 datagram for unknown stream ID "
                     << stream_id;
-    // TODO(b/181256914) buffer unknown HTTP/3 datagram flow IDs for a short
-    // period of time in case they were reordered.
+    // TODO(b/181256914) buffer HTTP/3 datagrams with unknown stream IDs for a
+    // short period of time in case they were reordered.
     return;
   }
   stream->OnDatagramReceived(&reader);
@@ -1840,12 +1788,8 @@
   switch (http_datagram_support) {
     case HttpDatagramSupport::kNone:
       return "None";
-    case HttpDatagramSupport::kDraft00:
-      return "Draft00";
     case HttpDatagramSupport::kDraft04:
       return "Draft04";
-    case HttpDatagramSupport::kDraft00And04:
-      return "Draft00And04";
   }
   return absl::StrCat("Unknown(", static_cast<int>(http_datagram_support), ")");
 }
diff --git a/quiche/quic/core/http/quic_spdy_session.h b/quiche/quic/core/http/quic_spdy_session.h
index 389691a..a6418b9 100644
--- a/quiche/quic/core/http/quic_spdy_session.h
+++ b/quiche/quic/core/http/quic_spdy_session.h
@@ -118,10 +118,8 @@
 // Whether draft-ietf-masque-h3-datagram is supported on this session and if so
 // which draft is currently in use.
 enum class HttpDatagramSupport : uint8_t {
-  kNone = 0,  // HTTP Datagrams are not supported for this session.
-  kDraft00 = 1,
-  kDraft04 = 2,
-  kDraft00And04 = 3,  // only used locally, we only negotiate one draft.
+  kNone,  // HTTP Datagrams are not supported for this session.
+  kDraft04,
 };
 
 QUIC_EXPORT_PRIVATE std::string HttpDatagramSupportToString(
@@ -378,17 +376,11 @@
   }
 
   // This must not be used except by QuicSpdyStream::SendHttp3Datagram.
-  MessageStatus SendHttp3Datagram(QuicDatagramStreamId stream_id,
+  MessageStatus SendHttp3Datagram(QuicStreamId stream_id,
                                   absl::string_view payload);
   // This must not be used except by QuicSpdyStream::SetMaxDatagramTimeInQueue.
   void SetMaxDatagramTimeInQueueForStreamId(QuicStreamId stream_id,
                                             QuicTime::Delta max_time_in_queue);
-  // This must not be used except by
-  // QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders.
-  void RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id,
-                                   QuicStreamId stream_id);
-  // This must not be used except by QuicSpdyStream::OnClose.
-  void UnregisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id);
 
   // Override from QuicSession to support HTTP/3 datagrams.
   void OnMessageReceived(absl::string_view message) override;
@@ -645,12 +637,6 @@
   // Whether the peer has indicated WebTransport support.
   bool peer_supports_webtransport_ = false;
 
-  // This maps from draft-ietf-masque-h3-datagram-00 flow IDs to stream IDs.
-  // TODO(b/181256914) remove this when we deprecate support for that draft in
-  // favor of more recent ones.
-  absl::flat_hash_map<uint64_t, QuicStreamId>
-      h3_datagram_flow_id_to_stream_id_map_;
-
   // Whether any settings have been received, either from the peer or from a
   // session ticket.
   bool any_settings_received_ = false;
diff --git a/quiche/quic/core/http/quic_spdy_session_test.cc b/quiche/quic/core/http/quic_spdy_session_test.cc
index accd1b0..84b50c7 100644
--- a/quiche/quic/core/http/quic_spdy_session_test.cc
+++ b/quiche/quic/core/http/quic_spdy_session_test.cc
@@ -582,11 +582,7 @@
     headers.OnHeaderBlockStart();
     headers.OnHeader(":method", "CONNECT");
     headers.OnHeader(":protocol", "webtransport");
-    if (session_.http_datagram_support() == HttpDatagramSupport::kDraft00) {
-      headers.OnHeader("datagram-flow-id", absl::StrCat(session_id));
-    } else {
-      headers.OnHeader("sec-webtransport-http3-draft02", "1");
-    }
+    headers.OnHeader("sec-webtransport-http3-draft02", "1");
     stream->OnStreamHeaderList(/*fin=*/true, 0, headers);
     WebTransportHttp3* web_transport =
         session_.GetWebTransportSession(session_id);
@@ -3389,16 +3385,9 @@
   switch (remote_support) {
     case HttpDatagramSupport::kNone:
       break;
-    case HttpDatagramSupport::kDraft00:
-      settings.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
-      break;
     case HttpDatagramSupport::kDraft04:
       settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
       break;
-    case HttpDatagramSupport::kDraft00And04:
-      settings.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
-      settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
-      break;
   }
   std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
   QuicStreamId stream_id =
@@ -3413,38 +3402,6 @@
   EXPECT_EQ(session_.SupportsH3Datagram(), expected_datagram_supported);
 }
 
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote00) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft00,
-      /*remote_support=*/HttpDatagramSupport::kDraft00,
-      /*expected_support=*/HttpDatagramSupport::kDraft00,
-      /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote04) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft00,
-      /*remote_support=*/HttpDatagramSupport::kDraft04,
-      /*expected_support=*/HttpDatagramSupport::kNone,
-      /*expected_datagram_supported=*/false);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote00And04) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft00,
-      /*remote_support=*/HttpDatagramSupport::kDraft00And04,
-      /*expected_support=*/HttpDatagramSupport::kDraft00,
-      /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote00) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft04,
-      /*remote_support=*/HttpDatagramSupport::kDraft00,
-      /*expected_support=*/HttpDatagramSupport::kNone,
-      /*expected_datagram_supported=*/false);
-}
-
 TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote04) {
   TestHttpDatagramSetting(
       /*local_support=*/HttpDatagramSupport::kDraft04,
@@ -3453,44 +3410,11 @@
       /*expected_datagram_supported=*/true);
 }
 
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote00And04) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft04,
-      /*remote_support=*/HttpDatagramSupport::kDraft00And04,
-      /*expected_support=*/HttpDatagramSupport::kDraft04,
-      /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00And04Remote00) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft00And04,
-      /*remote_support=*/HttpDatagramSupport::kDraft00,
-      /*expected_support=*/HttpDatagramSupport::kDraft00,
-      /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00And04Remote04) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft00And04,
-      /*remote_support=*/HttpDatagramSupport::kDraft04,
-      /*expected_support=*/HttpDatagramSupport::kDraft04,
-      /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient,
-       HttpDatagramSettingLocal00And04Remote00And04) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft00And04,
-      /*remote_support=*/HttpDatagramSupport::kDraft00And04,
-      /*expected_support=*/HttpDatagramSupport::kDraft04,
-      /*expected_datagram_supported=*/true);
-}
-
 TEST_P(QuicSpdySessionTestClient, WebTransportSetting) {
   if (!version().UsesHttp3()) {
     return;
   }
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
   session_.set_supports_webtransport(true);
 
   EXPECT_FALSE(session_.SupportsWebTransport());
@@ -3513,7 +3437,7 @@
   if (!version().UsesHttp3()) {
     return;
   }
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
   session_.set_supports_webtransport(true);
 
   EXPECT_FALSE(session_.SupportsWebTransport());
@@ -3543,7 +3467,7 @@
   if (!version().UsesHttp3()) {
     return;
   }
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
   session_.set_supports_webtransport(true);
 
   EXPECT_FALSE(session_.SupportsWebTransport());
@@ -3560,7 +3484,7 @@
   if (!version().UsesHttp3()) {
     return;
   }
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
   session_.set_supports_webtransport(true);
 
   CompleteHandshake();
@@ -3593,7 +3517,7 @@
   if (!version().UsesHttp3()) {
     return;
   }
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
   session_.set_supports_webtransport(true);
 
   CompleteHandshake();
@@ -3634,7 +3558,7 @@
   if (!version().UsesHttp3()) {
     return;
   }
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
   session_.set_supports_webtransport(true);
 
   CompleteHandshake();
@@ -3671,7 +3595,7 @@
   }
   SetQuicReloadableFlag(quic_verify_request_headers_2, true);
   SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
   session_.set_supports_webtransport(true);
 
   EXPECT_FALSE(session_.SupportsWebTransport());
diff --git a/quiche/quic/core/http/quic_spdy_stream.cc b/quiche/quic/core/http/quic_spdy_stream.cc
index bc3a664..4064d28 100644
--- a/quiche/quic/core/http/quic_spdy_stream.cc
+++ b/quiche/quic/core/http/quic_spdy_stream.cc
@@ -278,7 +278,6 @@
   MaybeProcessSentWebTransportHeaders(header_block);
 
   if (web_transport_ != nullptr &&
-      spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00 &&
       spdy_session_->perspective() == Perspective::IS_SERVER) {
     header_block["sec-webtransport-http3-draft"] = "draft02";
   }
@@ -296,24 +295,20 @@
 
   if (web_transport_ != nullptr &&
       session()->perspective() == Perspective::IS_CLIENT) {
-    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.
+      uint64_t capsule_type = 0xff37a2;  // REGISTER_DATAGRAM_NO_CONTEXT
+      constexpr unsigned char capsule_data[4] = {
+          0x80, 0xff, 0x7c, 0x00,  // WEBTRANSPORT datagram format type
+      };
+      WriteCapsule(Capsule::Unknown(
+          capsule_type,
+          absl::string_view(reinterpret_cast<const char*>(capsule_data),
+                            sizeof(capsule_data))));
       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.
-        uint64_t capsule_type = 0xff37a2;  // REGISTER_DATAGRAM_NO_CONTEXT
-        constexpr unsigned char capsule_data[4] = {
-            0x80, 0xff, 0x7c, 0x00,  // WEBTRANSPORT datagram format type
-        };
-        WriteCapsule(Capsule::Unknown(
-            capsule_type,
-            absl::string_view(reinterpret_cast<const char*>(capsule_data),
-                              sizeof(capsule_data))));
-        WriteGreaseCapsule();
-      }
     }
   }
 
@@ -906,10 +901,6 @@
     visitor->OnClose(this);
   }
 
-  if (datagram_flow_id_.has_value()) {
-    spdy_session_->UnregisterHttp3DatagramFlowId(datagram_flow_id_.value());
-  }
-
   if (web_transport_ != nullptr) {
     web_transport_->OnConnectStreamClosing();
   }
@@ -1261,8 +1252,6 @@
 
   std::string method;
   std::string protocol;
-  absl::optional<QuicDatagramStreamId> flow_id;
-  bool version_indicated = false;
   for (const auto& [header_name, header_value] : header_list_) {
     if (header_name == ":method") {
       if (!method.empty() || header_value.empty()) {
@@ -1277,21 +1266,10 @@
       protocol = header_value;
     }
     if (header_name == "datagram-flow-id") {
-      if (spdy_session_->http_datagram_support() !=
-          HttpDatagramSupport::kDraft00) {
-        QUIC_DLOG(ERROR) << ENDPOINT
-                         << "Rejecting WebTransport due to unexpected "
-                            "Datagram-Flow-Id header";
-        return;
-      }
-      if (flow_id.has_value() || header_value.empty()) {
-        return;
-      }
-      QuicDatagramStreamId flow_id_out;
-      if (!absl::SimpleAtoi(header_value, &flow_id_out)) {
-        return;
-      }
-      flow_id = flow_id_out;
+      QUIC_DLOG(ERROR) << ENDPOINT
+                       << "Rejecting WebTransport due to unexpected "
+                          "Datagram-Flow-Id header";
+      return;
     }
     if (header_name == "sec-webtransport-http3-draft02") {
       if (header_value != "1") {
@@ -1300,7 +1278,6 @@
                             "Sec-Webtransport-Http3-Draft02 header";
         return;
       }
-      version_indicated = true;
     }
   }
 
@@ -1308,24 +1285,6 @@
     return;
   }
 
-  if (!version_indicated &&
-      spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00) {
-    QUIC_DLOG(ERROR)
-        << ENDPOINT
-        << "WebTransport request rejected due to missing version header.";
-    return;
-  }
-
-  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00) {
-    if (!flow_id.has_value()) {
-      QUIC_DLOG(ERROR)
-          << ENDPOINT
-          << "Rejecting WebTransport due to missing Datagram-Flow-Id header";
-      return;
-    }
-    RegisterHttp3DatagramFlowId(*flow_id);
-  }
-
   web_transport_ =
       std::make_unique<WebTransportHttp3>(spdy_session_, this, id());
 }
@@ -1349,11 +1308,7 @@
     return;
   }
 
-  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00) {
-    headers["datagram-flow-id"] = absl::StrCat(id());
-  } else {
-    headers["sec-webtransport-http3-draft02"] = "1";
-  }
+  headers["sec-webtransport-http3-draft02"] = "1";
 
   web_transport_ =
       std::make_unique<WebTransportHttp3>(spdy_session_, this, id());
@@ -1493,9 +1448,7 @@
 }
 
 MessageStatus QuicSpdyStream::SendHttp3Datagram(absl::string_view payload) {
-  QuicDatagramStreamId stream_id =
-      datagram_flow_id_.has_value() ? datagram_flow_id_.value() : id();
-  return spdy_session_->SendHttp3Datagram(stream_id, payload);
+  return spdy_session_->SendHttp3Datagram(id(), payload);
 }
 
 void QuicSpdyStream::RegisterHttp3DatagramVisitor(
@@ -1557,20 +1510,11 @@
 QuicByteCount QuicSpdyStream::GetMaxDatagramSize() const {
   QuicByteCount prefix_size = 0;
   switch (spdy_session_->http_datagram_support()) {
-    case HttpDatagramSupport::kDraft00:
-      if (!datagram_flow_id_.has_value()) {
-        QUIC_BUG(GetMaxDatagramSize with no flow ID)
-            << "GetMaxDatagramSize() called when no flow ID available";
-        break;
-      }
-      prefix_size = QuicDataWriter::GetVarInt62Len(*datagram_flow_id_);
-      break;
     case HttpDatagramSupport::kDraft04:
       prefix_size =
           QuicDataWriter::GetVarInt62Len(id() / kHttpDatagramStreamIdDivisor);
       break;
     case HttpDatagramSupport::kNone:
-    case HttpDatagramSupport::kDraft00And04:
       QUIC_BUG(GetMaxDatagramSize called with no datagram support)
           << "GetMaxDatagramSize() called when no HTTP/3 datagram support has "
              "been negotiated.  Support value: "
@@ -1593,11 +1537,6 @@
   return max_datagram_size - prefix_size;
 }
 
-void QuicSpdyStream::RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id) {
-  datagram_flow_id_ = flow_id;
-  spdy_session_->RegisterHttp3DatagramFlowId(datagram_flow_id_.value(), id());
-}
-
 void QuicSpdyStream::HandleBodyAvailable() {
   if (!capsule_parser_) {
     OnBodyAvailable();
diff --git a/quiche/quic/core/http/quic_spdy_stream.h b/quiche/quic/core/http/quic_spdy_stream.h
index 8e0c441..61cd7e3 100644
--- a/quiche/quic/core/http/quic_spdy_stream.h
+++ b/quiche/quic/core/http/quic_spdy_stream.h
@@ -262,8 +262,7 @@
     virtual ~Http3DatagramVisitor() {}
 
     // Called when an HTTP/3 datagram is received. |payload| does not contain
-    // the stream ID. Note that this contains the stream ID even if flow IDs
-    // from draft-ietf-masque-h3-datagram-00 are in use.
+    // the stream ID.
     virtual void OnHttp3Datagram(QuicStreamId stream_id,
                                  absl::string_view payload) = 0;
   };
@@ -285,10 +284,6 @@
 
   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() const;
 
   // Writes |capsule| onto the DATA stream.
@@ -467,9 +462,6 @@
 
   // HTTP/3 Datagram support.
   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_;
 };
 
 }  // 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 de8a5be..80d9ee2 100644
--- a/quiche/quic/core/http/quic_spdy_stream_test.cc
+++ b/quiche/quic/core/http/quic_spdy_stream_test.cc
@@ -3075,39 +3075,13 @@
   }
 }
 
-TEST_P(QuicSpdyStreamTest, ProcessOutgoingWebTransportHeadersDatagramDraft00) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_->EnableWebTransport();
-  session_->OnSetting(SETTINGS_ENABLE_CONNECT_PROTOCOL, 1);
-  QuicSpdySessionPeer::EnableWebTransport(session_.get());
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft00);
-
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
-      .Times(AnyNumber());
-
-  spdy::SpdyHeaderBlock headers;
-  headers[":method"] = "CONNECT";
-  headers[":protocol"] = "webtransport";
-  headers["datagram-flow-id"] = absl::StrCat(stream_->id());
-  stream_->WriteHeaders(std::move(headers), /*fin=*/false, nullptr);
-  ASSERT_TRUE(stream_->web_transport() != nullptr);
-  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
-}
-
 TEST_P(QuicSpdyStreamTest, ProcessOutgoingWebTransportHeadersDatagramDraft04) {
   if (!UsesHttp3()) {
     return;
   }
 
   InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
   session_->EnableWebTransport();
   session_->OnSetting(SETTINGS_ENABLE_CONNECT_PROTOCOL, 1);
   QuicSpdySessionPeer::EnableWebTransport(session_.get());
@@ -3132,7 +3106,7 @@
   }
 
   Initialize(kShouldProcessData);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
   session_->EnableWebTransport();
   QuicSpdySessionPeer::EnableWebTransport(session_.get());
   QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
@@ -3152,104 +3126,7 @@
   EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
 }
 
-TEST_P(QuicSpdyStreamTest, ProcessIncomingWebTransportHeadersDatagramDraft00) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_->EnableWebTransport();
-  QuicSpdySessionPeer::EnableWebTransport(session_.get());
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft00);
-
-  headers_[":method"] = "CONNECT";
-  headers_[":protocol"] = "webtransport";
-  headers_["datagram-flow-id"] = absl::StrCat(stream_->id());
-
-  stream_->OnStreamHeadersPriority(
-      spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  ProcessHeaders(false, headers_);
-  EXPECT_EQ("", stream_->data());
-  EXPECT_FALSE(stream_->header_list().empty());
-  EXPECT_FALSE(stream_->IsDoneReading());
-  ASSERT_TRUE(stream_->web_transport() != nullptr);
-  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
-}
-
-TEST_P(QuicSpdyStreamTest,
-       ProcessIncomingWebTransportHeadersWithMismatchedFlowId) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  // TODO(b/181256914) Remove this test when we deprecate
-  // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
-
-  Initialize(kShouldProcessData);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_->EnableWebTransport();
-  QuicSpdySessionPeer::EnableWebTransport(session_.get());
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft00);
-
-  headers_[":method"] = "CONNECT";
-  headers_[":protocol"] = "webtransport";
-  headers_["datagram-flow-id"] = "2";
-
-  stream_->OnStreamHeadersPriority(
-      spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  ProcessHeaders(false, headers_);
-  EXPECT_EQ("", stream_->data());
-  EXPECT_FALSE(stream_->header_list().empty());
-  EXPECT_FALSE(stream_->IsDoneReading());
-  ASSERT_TRUE(stream_->web_transport() != nullptr);
-  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
-}
-
-TEST_P(QuicSpdyStreamTest, ReceiveHttpDatagramDraft00) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft00);
-  headers_[":method"] = "CONNECT";
-  headers_[":protocol"] = "webtransport";
-  headers_["datagram-flow-id"] = absl::StrCat(stream_->id());
-  ProcessHeaders(false, headers_);
-  session_->RegisterHttp3DatagramFlowId(stream_->id(), stream_->id());
-  SavingHttp3DatagramVisitor h3_datagram_visitor;
-  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_->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(), std::string(&datagram[1], datagram.size() - 1)}));
-  // Test move.
-  SavingHttp3DatagramVisitor 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(), std::string(&datagram[1], datagram.size() - 1)}));
-  // Cleanup.
-  stream_->UnregisterHttp3DatagramVisitor();
-  session_->UnregisterHttp3DatagramFlowId(stream_->id());
-}
-
-TEST_P(QuicSpdyStreamTest, ReceiveHttpDatagramDraft04) {
+TEST_P(QuicSpdyStreamTest, ReceiveHttpDatagram) {
   if (!UsesHttp3()) {
     return;
   }
@@ -3294,7 +3171,7 @@
     return;
   }
   Initialize(kShouldProcessData);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
   QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
                                               HttpDatagramSupport::kDraft04);
   std::string http_datagram_payload = {1, 2, 3, 4, 5, 6};
@@ -3309,7 +3186,7 @@
     return;
   }
   Initialize(kShouldProcessData);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
   QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
                                               HttpDatagramSupport::kDraft04);
   EXPECT_GT(stream_->GetMaxDatagramSize(), 512u);
diff --git a/quiche/quic/core/http/spdy_utils.cc b/quiche/quic/core/http/spdy_utils.cc
index d0eac9f..b8282e4 100644
--- a/quiche/quic/core/http/spdy_utils.cc
+++ b/quiche/quic/core/http/spdy_utils.cc
@@ -155,47 +155,6 @@
 }
 
 // static
-absl::optional<QuicDatagramStreamId> SpdyUtils::ParseDatagramFlowIdHeader(
-    const spdy::SpdyHeaderBlock& headers) {
-  auto flow_id_pair = headers.find("datagram-flow-id");
-  if (flow_id_pair == headers.end()) {
-    return absl::nullopt;
-  }
-  std::vector<absl::string_view> flow_id_strings =
-      absl::StrSplit(flow_id_pair->second, ',');
-  absl::optional<QuicDatagramStreamId> first_named_flow_id;
-  for (absl::string_view flow_id_string : flow_id_strings) {
-    std::vector<absl::string_view> flow_id_components =
-        absl::StrSplit(flow_id_string, ';');
-    if (flow_id_components.empty()) {
-      continue;
-    }
-    absl::string_view flow_id_value_string = flow_id_components[0];
-    quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(
-        &flow_id_value_string);
-    QuicDatagramStreamId flow_id;
-    if (!absl::SimpleAtoi(flow_id_value_string, &flow_id)) {
-      continue;
-    }
-    if (flow_id_components.size() == 1) {
-      // This flow ID is unnamed, return this one.
-      return flow_id;
-    }
-    // Otherwise this is a named flow ID.
-    if (!first_named_flow_id.has_value()) {
-      first_named_flow_id = flow_id;
-    }
-  }
-  return first_named_flow_id;
-}
-
-// static
-void SpdyUtils::AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
-                                        QuicDatagramStreamId flow_id) {
-  (*headers)["datagram-flow-id"] = absl::StrCat(flow_id);
-}
-
-// static
 ParsedQuicVersion SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
     const spdy::SpdyAltSvcWireFormat::AlternativeService&
         alternative_service_entry,
diff --git a/quiche/quic/core/http/spdy_utils.h b/quiche/quic/core/http/spdy_utils.h
index 5654b2f..d88087c 100644
--- a/quiche/quic/core/http/spdy_utils.h
+++ b/quiche/quic/core/http/spdy_utils.h
@@ -54,15 +54,6 @@
   static bool PopulateHeaderBlockFromUrl(const std::string url,
                                          spdy::SpdyHeaderBlock* headers);
 
-  // Parses the "datagram-flow-id" header, returns the flow ID on success, or
-  // returns absl::nullopt if the header was not present or failed to parse.
-  static absl::optional<QuicDatagramStreamId> ParseDatagramFlowIdHeader(
-      const spdy::SpdyHeaderBlock& headers);
-
-  // Adds the "datagram-flow-id" header.
-  static void AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
-                                      QuicDatagramStreamId flow_id);
-
   // Returns the advertised QUIC version from the specified alternative service
   // advertisement, or ParsedQuicVersion::Unsupported() if no supported version
   // is advertised.
diff --git a/quiche/quic/core/http/spdy_utils_test.cc b/quiche/quic/core/http/spdy_utils_test.cc
index d22a0e8..718d548 100644
--- a/quiche/quic/core/http/spdy_utils_test.cc
+++ b/quiche/quic/core/http/spdy_utils_test.cc
@@ -34,14 +34,6 @@
   return headers;
 }
 
-static void ValidateDatagramFlowId(
-    const std::string& header_value,
-    absl::optional<QuicDatagramStreamId> expected_flow_id) {
-  SpdyHeaderBlock headers;
-  headers["datagram-flow-id"] = header_value;
-  ASSERT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), expected_flow_id);
-}
-
 }  // anonymous namespace
 
 using CopyAndValidateHeaders = QuicTest;
@@ -386,30 +378,6 @@
       SpdyUtils::PopulateHeaderBlockFromUrl("www.google.com/", &headers));
 }
 
-using DatagramFlowIdTest = QuicTest;
-
-TEST_F(DatagramFlowIdTest, DatagramFlowId) {
-  // Test missing header.
-  SpdyHeaderBlock headers;
-  EXPECT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), absl::nullopt);
-  // Add header and verify it parses.
-  QuicDatagramStreamId flow_id = 123;
-  SpdyUtils::AddDatagramFlowIdHeader(&headers, flow_id);
-  EXPECT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), flow_id);
-  // Test empty header.
-  ValidateDatagramFlowId("", absl::nullopt);
-  // Test invalid header.
-  ValidateDatagramFlowId("M4SQU3", absl::nullopt);
-  // Test simple header.
-  ValidateDatagramFlowId("42", 42);
-  // Test with parameter.
-  ValidateDatagramFlowId("42; abc=def", 42);
-  // Test list.
-  ValidateDatagramFlowId("42, 44; ecn-ect0, 46; ecn-ect1, 48; ecn-ce", 42);
-  // Test reordered list.
-  ValidateDatagramFlowId("44; ecn-ect0, 42, 48; ecn-ce, 46; ecn-ect1", 42);
-}
-
 using ExtractQuicVersionFromAltSvcEntry = QuicTest;
 
 TEST_F(ExtractQuicVersionFromAltSvcEntry, SupportedVersion) {
diff --git a/quiche/quic/core/http/web_transport_http3.cc b/quiche/quic/core/http/web_transport_http3.cc
index e10e8ad..6c9cbff 100644
--- a/quiche/quic/core/http/web_transport_http3.cc
+++ b/quiche/quic/core/http/web_transport_http3.cc
@@ -179,7 +179,6 @@
       return;
     }
     bool should_validate_version =
-        session_->http_datagram_support() != HttpDatagramSupport::kDraft00 &&
         session_->ShouldValidateWebTransportVersion();
     if (should_validate_version) {
       auto draft_version_it = headers.find("sec-webtransport-http3-draft");
diff --git a/quiche/quic/core/quic_constants.h b/quiche/quic/core/quic_constants.h
index 3fc4c8b..6f89ec1 100644
--- a/quiche/quic/core/quic_constants.h
+++ b/quiche/quic/core/quic_constants.h
@@ -307,13 +307,6 @@
 QUIC_EXPORT_PRIVATE extern const char* const kEPIDGoogleFrontEnd;
 QUIC_EXPORT_PRIVATE extern const char* const kEPIDGoogleFrontEnd0;
 
-// HTTP/3 Datagrams.
-enum : QuicDatagramContextId {
-  kFirstDatagramContextIdClient = 0,
-  kFirstDatagramContextIdServer = 1,
-  kDatagramContextIdIncrement = 2,
-};
-
 enum : uint64_t {
   kHttpDatagramStreamIdDivisor = 4,
 };
diff --git a/quiche/quic/core/quic_types.h b/quiche/quic/core/quic_types.h
index c21030b..c40eb29 100644
--- a/quiche/quic/core/quic_types.h
+++ b/quiche/quic/core/quic_types.h
@@ -28,13 +28,6 @@
 using QuicControlFrameId = uint32_t;
 using QuicMessageId = uint32_t;
 
-// TODO(b/181256914) replace QuicDatagramStreamId with QuicStreamId once we
-// remove support for draft-ietf-masque-h3-datagram-00 in favor of later drafts.
-using QuicDatagramStreamId = uint64_t;
-using QuicDatagramContextId = uint64_t;
-// Note that for draft-ietf-masque-h3-datagram-00, we represent the flow ID as a
-// QuicDatagramStreamId.
-
 // IMPORTANT: IETF QUIC defines stream IDs and stream counts as being unsigned
 // 62-bit numbers. However, we have decided to only support up to 2^32-1 streams
 // in order to reduce the size of data structures such as QuicStreamFrame
diff --git a/quiche/quic/masque/masque_client_session.cc b/quiche/quic/masque/masque_client_session.cc
index b053659..4dcdb45 100644
--- a/quiche/quic/masque/masque_client_session.cc
+++ b/quiche/quic/masque/masque_client_session.cc
@@ -123,9 +123,6 @@
   headers[":authority"] = authority;
   headers[":path"] = canonicalized_path;
   headers["connect-udp-version"] = "6";
-  if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
-    SpdyUtils::AddDatagramFlowIdHeader(&headers, stream->id());
-  }
   size_t bytes_sent =
       stream->SendRequest(std::move(headers), /*body=*/"", /*fin=*/false);
   if (bytes_sent == 0) {
diff --git a/quiche/quic/masque/masque_client_session.h b/quiche/quic/masque/masque_client_session.h
index 05162b5..41c63a9 100644
--- a/quiche/quic/masque/masque_client_session.h
+++ b/quiche/quic/masque/masque_client_session.h
@@ -125,7 +125,7 @@
   };
 
   HttpDatagramSupport LocalHttpDatagramSupport() override {
-    return HttpDatagramSupport::kDraft00And04;
+    return HttpDatagramSupport::kDraft04;
   }
 
   const ConnectUdpClientState* GetOrCreateConnectUdpClientState(
diff --git a/quiche/quic/masque/masque_server_session.cc b/quiche/quic/masque/masque_server_session.cc
index 3a81caa..bfc8cdf 100644
--- a/quiche/quic/masque/masque_server_session.cc
+++ b/quiche/quic/masque/masque_server_session.cc
@@ -174,16 +174,6 @@
                      << "\"";
     return CreateBackendErrorResponse("400", "Bad protocol");
   }
-  absl::optional<QuicDatagramStreamId> flow_id;
-  if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
-    flow_id = SpdyUtils::ParseDatagramFlowIdHeader(request_headers);
-    if (!flow_id.has_value()) {
-      QUIC_DLOG(ERROR)
-          << "MASQUE request with bad or missing DatagramFlowId header";
-      return CreateBackendErrorResponse("400",
-                                        "Bad or missing DatagramFlowId header");
-    }
-  }
   // Extract target host and port from path using default template.
   std::vector<absl::string_view> path_split = absl::StrSplit(path, '/');
   if (path_split.size() != 4 || !path_split[0].empty() ||
@@ -221,10 +211,8 @@
   QuicSocketAddress target_server_address(info_list->ai_addr,
                                           info_list->ai_addrlen);
   QUIC_DLOG(INFO) << "Got CONNECT_UDP request on stream ID "
-                  << request_handler->stream_id() << " flow_id="
-                  << (flow_id.has_value() ? absl::StrCat(*flow_id) : "none")
-                  << " target_server_address=\"" << target_server_address
-                  << "\"";
+                  << request_handler->stream_id() << " target_server_address=\""
+                  << target_server_address << "\"";
 
   FdWrapper fd_wrapper(target_server_address.host().AddressFamilyToInt());
   if (fd_wrapper.fd() == kQuicInvalidSocketFd) {
@@ -250,23 +238,11 @@
         << request_handler->stream_id();
     return CreateBackendErrorResponse("500", "Bad stream type");
   }
-  if (flow_id.has_value()) {
-    stream->RegisterHttp3DatagramFlowId(*flow_id);
-  }
   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->RegisterHttp3DatagramVisitor(&connect_udp_server_states_.back());
-  }
-
   spdy::Http2HeaderBlock response_headers;
   response_headers[":status"] = "200";
-  if (flow_id.has_value()) {
-    SpdyUtils::AddDatagramFlowIdHeader(&response_headers, *flow_id);
-  }
   auto response = std::make_unique<QuicBackendResponse>();
   response->set_response_type(QuicBackendResponse::INCOMPLETE_RESPONSE);
   response->set_headers(std::move(response_headers));
diff --git a/quiche/quic/masque/masque_server_session.h b/quiche/quic/masque/masque_server_session.h
index b3d2dde..922e710 100644
--- a/quiche/quic/masque/masque_server_session.h
+++ b/quiche/quic/masque/masque_server_session.h
@@ -97,7 +97,7 @@
   // From QuicSpdySession.
   bool OnSettingsFrame(const SettingsFrame& frame) override;
   HttpDatagramSupport LocalHttpDatagramSupport() override {
-    return HttpDatagramSupport::kDraft00And04;
+    return HttpDatagramSupport::kDraft04;
   }
 
   MasqueServerBackend* masque_server_backend_;  // Unowned.
diff --git a/quiche/quic/tools/quic_simple_server_session.h b/quiche/quic/tools/quic_simple_server_session.h
index 5be9a3d..0530ce2 100644
--- a/quiche/quic/tools/quic_simple_server_session.h
+++ b/quiche/quic/tools/quic_simple_server_session.h
@@ -97,7 +97,7 @@
   }
   HttpDatagramSupport LocalHttpDatagramSupport() override {
     if (ShouldNegotiateWebTransport()) {
-      return HttpDatagramSupport::kDraft00And04;
+      return HttpDatagramSupport::kDraft04;
     }
     return QuicServerSessionBase::LocalHttpDatagramSupport();
   }