diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index db6dbe04e4c94b7f5c8e8ea05fb2f8ff7bc9ab00..26bfa02ad1d1dcda5dc4324cbfd5092384ee2ee1 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -897,7 +897,12 @@ grpc_metadata_buffer *grpc_call_get_metadata_buffer(grpc_call *call) {
 static void call_alarm(void *arg, int success) {
   grpc_call *call = arg;
   if (success) {
-    grpc_call_cancel(call);
+    if (call->is_client) {
+      grpc_call_cancel_with_status(call, GRPC_STATUS_DEADLINE_EXCEEDED,
+                                   "Deadline Exceeded");
+    } else {
+      grpc_call_cancel(call);
+    }
   }
   grpc_call_internal_unref(call);
 }
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index 88a6acdd7d9065c2c882ad9c2c086df55f832b95..4327b9129873d7eb1ab5b8354c6ef4ef962efd40 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -154,8 +154,9 @@ void test_connect(const char *server_host, const char *client_host, int port,
     /* Check for a failed connection. */
     cq_expect_invoke_accepted(v_client, tag(1), GRPC_OP_ERROR);
     cq_expect_client_metadata_read(v_client, tag(2), NULL);
-    cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_CANCELLED,
-                                   NULL, NULL);
+    cq_expect_finished_with_status(v_client, tag(3),
+                                   GRPC_STATUS_DEADLINE_EXCEEDED,
+                                   "Deadline Exceeded", NULL);
     cq_verify(v_client);
 
     grpc_call_destroy(c);
diff --git a/test/core/end2end/gen_build_json.py b/test/core/end2end/gen_build_json.py
index b91995bc76d6625416531b7a2bdc0f5d9dcebecc..8aedc8eafc82bc0fc9a0751e157f3ef78275d243 100755
--- a/test/core/end2end/gen_build_json.py
+++ b/test/core/end2end/gen_build_json.py
@@ -55,7 +55,8 @@ def main():
               'name': 'end2end_test_%s' % t,
               'build': 'private',
               'secure': False,
-              'src': ['test/core/end2end/tests/%s.c' % t]
+              'src': ['test/core/end2end/tests/%s.c' % t],
+              'headers': ['test/core/end2end/tests/cancel_test_helpers.h']
           }
           for t in END2END_TESTS] + [
           {
diff --git a/test/core/end2end/no_server_test.c b/test/core/end2end/no_server_test.c
index ba6349c109b470d8bda94f83fe09be03ec7ac015..b9660f14b3007fd6fb4217f87fd275e5596a1130 100644
--- a/test/core/end2end/no_server_test.c
+++ b/test/core/end2end/no_server_test.c
@@ -62,8 +62,8 @@ int main(int argc, char **argv) {
   /* verify that all tags get completed */
   cq_expect_invoke_accepted(cqv, tag(1), GRPC_OP_ERROR);
   cq_expect_client_metadata_read(cqv, tag(2), NULL);
-  cq_expect_finished_with_status(cqv, tag(3), GRPC_STATUS_CANCELLED, NULL,
-                                 NULL);
+  cq_expect_finished_with_status(cqv, tag(3), GRPC_STATUS_DEADLINE_EXCEEDED,
+                                 "Deadline Exceeded", NULL);
   cq_verify(cqv);
 
   grpc_completion_queue_shutdown(cq);
diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c
index 85686051970f822ae4efb635eedb373dc411fed1..cfbb4796aaee1d38365fc6a64f877e0010899632 100644
--- a/test/core/end2end/tests/cancel_after_accept.c
+++ b/test/core/end2end/tests/cancel_after_accept.c
@@ -43,14 +43,7 @@
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 #include "test/core/end2end/cq_verifier.h"
-
-/* allow cancellation by either grpc_call_cancel, or by wait_for_deadline (which
- * does nothing) */
-typedef grpc_call_error (*canceller)(grpc_call *call);
-
-static grpc_call_error wait_for_deadline(grpc_call *call) {
-  return GRPC_CALL_OK;
-}
+#include "test/core/end2end/tests/cancel_test_helpers.h"
 
 enum { TIMEOUT = 200000 };
 
@@ -112,7 +105,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
 
 /* Cancel after accept, no payload */
 static void test_cancel_after_accept(grpc_end2end_test_config config,
-                                     canceller call_cancel) {
+                                     cancellation_mode mode) {
   grpc_call *c;
   grpc_call *s;
   grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL);
@@ -138,10 +131,10 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
   cq_expect_client_metadata_read(v_client, tag(2), NULL);
   cq_verify(v_client);
 
-  GPR_ASSERT(GRPC_CALL_OK == call_cancel(c));
+  GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c));
 
-  cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_CANCELLED, NULL,
-                                 NULL);
+  cq_expect_finished_with_status(v_client, tag(3), mode.expect_status,
+                                 mode.expect_details, NULL);
   cq_verify(v_client);
 
   cq_expect_finished_with_status(v_server, tag(102), GRPC_STATUS_CANCELLED,
@@ -159,9 +152,8 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
 
 void grpc_end2end_tests(grpc_end2end_test_config config) {
   int i;
-  canceller cancellers[2] = {grpc_call_cancel, wait_for_deadline};
 
-  for (i = 0; i < GPR_ARRAY_SIZE(cancellers); i++) {
-    test_cancel_after_accept(config, cancellers[i]);
+  for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) {
+    test_cancel_after_accept(config, cancellation_modes[i]);
   }
 }
diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
index 798051f01b2971ed853752d0dc2ba51cc866f104..74670bdc91672e416fb556e3df9f97f4d89e2d57 100644
--- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
+++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
@@ -43,14 +43,7 @@
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 #include "test/core/end2end/cq_verifier.h"
-
-/* allow cancellation by either grpc_call_cancel, or by wait_for_deadline (which
- * does nothing) */
-typedef grpc_call_error (*canceller)(grpc_call *call);
-
-static grpc_call_error wait_for_deadline(grpc_call *call) {
-  return GRPC_CALL_OK;
-}
+#include "test/core/end2end/tests/cancel_test_helpers.h"
 
 enum { TIMEOUT = 200000 };
 
@@ -112,7 +105,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
 
 /* Cancel after accept with a writes closed, no payload */
 static void test_cancel_after_accept_and_writes_closed(
-    grpc_end2end_test_config config, canceller call_cancel) {
+    grpc_end2end_test_config config, cancellation_mode mode) {
   grpc_call *c;
   grpc_call *s;
   grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL);
@@ -146,10 +139,10 @@ static void test_cancel_after_accept_and_writes_closed(
   cq_expect_empty_read(v_server, tag(101));
   cq_verify(v_server);
 
-  GPR_ASSERT(GRPC_CALL_OK == call_cancel(c));
+  GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c));
 
-  cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_CANCELLED, NULL,
-                                 NULL);
+  cq_expect_finished_with_status(v_client, tag(3), mode.expect_status,
+                                 mode.expect_details, NULL);
   cq_verify(v_client);
 
   cq_expect_finished_with_status(v_server, tag(102), GRPC_STATUS_CANCELLED,
@@ -167,9 +160,8 @@ static void test_cancel_after_accept_and_writes_closed(
 
 void grpc_end2end_tests(grpc_end2end_test_config config) {
   int i;
-  canceller cancellers[2] = {grpc_call_cancel, wait_for_deadline};
 
-  for (i = 0; i < GPR_ARRAY_SIZE(cancellers); i++) {
-    test_cancel_after_accept_and_writes_closed(config, cancellers[i]);
+  for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) {
+    test_cancel_after_accept_and_writes_closed(config, cancellation_modes[i]);
   }
 }
diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c
index 3c9122944bd1eb07d32b0dbaa7c8fc5d5910bb26..d4cb5e4f133f021fe9c76f238d792fb740c5be70 100644
--- a/test/core/end2end/tests/cancel_after_invoke.c
+++ b/test/core/end2end/tests/cancel_after_invoke.c
@@ -43,14 +43,7 @@
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 #include "test/core/end2end/cq_verifier.h"
-
-/* allow cancellation by either grpc_call_cancel, or by wait_for_deadline (which
- * does nothing) */
-typedef grpc_call_error (*canceller)(grpc_call *call);
-
-static grpc_call_error wait_for_deadline(grpc_call *call) {
-  return GRPC_CALL_OK;
-}
+#include "test/core/end2end/tests/cancel_test_helpers.h"
 
 enum { TIMEOUT = 200000 };
 
@@ -112,7 +105,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
 
 /* Cancel after invoke, no payload */
 static void test_cancel_after_invoke(grpc_end2end_test_config config,
-                                     canceller call_cancel) {
+                                     cancellation_mode mode) {
   grpc_call *c;
   grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL);
   gpr_timespec deadline = five_seconds_time();
@@ -126,11 +119,11 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
   cq_expect_invoke_accepted(v_client, tag(1), GRPC_OP_OK);
   cq_verify(v_client);
 
-  GPR_ASSERT(GRPC_CALL_OK == call_cancel(c));
+  GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c));
 
   cq_expect_client_metadata_read(v_client, tag(2), NULL);
-  cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_CANCELLED, NULL,
-                                 NULL);
+  cq_expect_finished_with_status(v_client, tag(3), mode.expect_status,
+                                 mode.expect_details, NULL);
   cq_verify(v_client);
 
   grpc_call_destroy(c);
@@ -142,9 +135,8 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
 
 void grpc_end2end_tests(grpc_end2end_test_config config) {
   int i;
-  canceller cancellers[2] = {grpc_call_cancel, wait_for_deadline};
 
-  for (i = 0; i < GPR_ARRAY_SIZE(cancellers); i++) {
-    test_cancel_after_invoke(config, cancellers[i]);
+  for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) {
+    test_cancel_after_invoke(config, cancellation_modes[i]);
   }
 }
diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c
index d5edcd4ac177d60ef08bb5344f4349a67bc0d91d..f799cba71d6180f9c32ca19a5b5f9bcaae360582 100644
--- a/test/core/end2end/tests/cancel_before_invoke.c
+++ b/test/core/end2end/tests/cancel_before_invoke.c
@@ -44,10 +44,6 @@
 #include <grpc/support/useful.h>
 #include "test/core/end2end/cq_verifier.h"
 
-/* allow cancellation by either grpc_call_cancel, or by wait_for_deadline (which
- * does nothing) */
-typedef grpc_call_error (*canceller)(grpc_call *call);
-
 enum { TIMEOUT = 200000 };
 
 static void *tag(gpr_intptr t) { return (void *)t; }
diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c
index 0c684acf0a935dcbae6496a07c19b660db2b2097..e4f9deecd1b948378d40fcbf872c84e4f2a68e8d 100644
--- a/test/core/end2end/tests/cancel_in_a_vacuum.c
+++ b/test/core/end2end/tests/cancel_in_a_vacuum.c
@@ -43,14 +43,7 @@
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 #include "test/core/end2end/cq_verifier.h"
-
-/* allow cancellation by either grpc_call_cancel, or by wait_for_deadline (which
- * does nothing) */
-typedef grpc_call_error (*canceller)(grpc_call *call);
-
-static grpc_call_error wait_for_deadline(grpc_call *call) {
-  return GRPC_CALL_OK;
-}
+#include "test/core/end2end/tests/cancel_test_helpers.h"
 
 enum { TIMEOUT = 200000 };
 
@@ -110,7 +103,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
 
 /* Cancel and do nothing */
 static void test_cancel_in_a_vacuum(grpc_end2end_test_config config,
-                                    canceller call_cancel) {
+                                    cancellation_mode mode) {
   grpc_call *c;
   grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL);
   gpr_timespec deadline = five_seconds_time();
@@ -119,7 +112,7 @@ static void test_cancel_in_a_vacuum(grpc_end2end_test_config config,
   c = grpc_channel_create_call(f.client, "/foo", "test.google.com", deadline);
   GPR_ASSERT(c);
 
-  GPR_ASSERT(GRPC_CALL_OK == call_cancel(c));
+  GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c));
 
   grpc_call_destroy(c);
 
@@ -130,9 +123,8 @@ static void test_cancel_in_a_vacuum(grpc_end2end_test_config config,
 
 void grpc_end2end_tests(grpc_end2end_test_config config) {
   int i;
-  canceller cancellers[2] = {grpc_call_cancel, wait_for_deadline};
 
-  for (i = 0; i < GPR_ARRAY_SIZE(cancellers); i++) {
-    test_cancel_in_a_vacuum(config, cancellers[i]);
+  for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) {
+    test_cancel_in_a_vacuum(config, cancellation_modes[i]);
   }
 }
diff --git a/test/core/end2end/tests/cancel_test_helpers.h b/test/core/end2end/tests/cancel_test_helpers.h
new file mode 100644
index 0000000000000000000000000000000000000000..bc6bfa94248903a760f0cf267fb4b0fa3df56fdb
--- /dev/null
+++ b/test/core/end2end/tests/cancel_test_helpers.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_TEST_END2END_TESTS_CANCEL_TEST_HELPERS_H__
+#define __GRPC_TEST_END2END_TESTS_CANCEL_TEST_HELPERS_H__
+
+typedef struct {
+  grpc_call_error (*initiate_cancel)(grpc_call *call);
+  grpc_status_code expect_status;
+  const char *expect_details;
+} cancellation_mode;
+
+static grpc_call_error wait_for_deadline(grpc_call *call) {
+  return GRPC_CALL_OK;
+}
+
+static const cancellation_mode cancellation_modes[] = {
+    {grpc_call_cancel, GRPC_STATUS_CANCELLED, NULL},
+    {wait_for_deadline, GRPC_STATUS_DEADLINE_EXCEEDED, "Deadline Exceeded"},
+};
+
+#endif
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 3a1da68e47ff89432091f8a4b3879d49606fd04f..4dea77ea8118d94a224e0106d822fdef54b59c20 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -210,9 +210,7 @@ TEST_F(End2endTest, RpcDeadlineExpires) {
       std::chrono::system_clock::now() + std::chrono::microseconds(10);
   context.set_absolute_deadline(deadline);
   Status s = stub_->Echo(&context, request, &response);
-  // TODO(yangg) use correct error code when b/18793983 is fixed.
-  // EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.code());
-  EXPECT_EQ(StatusCode::CANCELLED, s.code());
+  EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.code());
 }
 
 // Set a long but finite deadline.