diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c
index 464c1f6ae3ff16f53bb2525730b28a9dfef1e1eb..904282748437716aa23523cd68d16acbef90358f 100644
--- a/src/core/iomgr/pollset_posix.c
+++ b/src/core/iomgr/pollset_posix.c
@@ -352,6 +352,7 @@ static void basic_do_promote(grpc_exec_ctx *exec_ctx, void *args, int success) {
   if (pollset->shutting_down) {
     /* We don't care about this pollset anymore. */
     if (pollset->in_flight_cbs == 0 && !pollset->called_shutdown) {
+      pollset->called_shutdown = 1;
       finish_shutdown(exec_ctx, pollset);
     }
   } else if (grpc_fd_is_orphaned(fd)) {
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 0437dbfadf3ed92f3655e65b1fc95ecac1904934..de743795462968dc2340b141bfd73a721d744843 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -1136,7 +1136,7 @@ static void recv_data(grpc_exec_ctx *exec_ctx, void *tp, int success) {
     grpc_chttp2_publish_reads(exec_ctx, &t->global, &t->parsing);
     t->parsing_active = 0;
   }
-  if (!success || i != t->read_buffer.count) {
+  if (!success || i != t->read_buffer.count || t->closed) {
     drop_connection(exec_ctx, t);
     read_error_locked(exec_ctx, t);
   } else if (!t->closed) {
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 02d1f7ac4f9a6a6d267d493ae60af0a2bc9e7b51..89a556c5877ba8a7e923eb7a300992d242acacba 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -683,10 +683,14 @@ TEST_P(End2endTest, RequestStreamServerEarlyCancelTest) {
   auto stream = stub_->RequestStream(&context, &response);
   request.set_message("hello");
   int send_messages = 20;
-  while (send_messages > 0) {
+  while (send_messages > 10) {
     EXPECT_TRUE(stream->Write(request));
     send_messages--;
   }
+  while (send_messages > 0) {
+    stream->Write(request);
+    send_messages--;
+  }
   stream->WritesDone();
   Status s = stream->Finish();
   EXPECT_EQ(s.error_code(), StatusCode::CANCELLED);