API fuzzer compiles with new error handling
diff --git a/BUILD b/BUILD
index c28d0e7..0804989 100644
--- a/BUILD
+++ b/BUILD
@@ -272,6 +272,7 @@
     "src/core/lib/security/transport/handshake.h",
     "src/core/lib/security/transport/secure_endpoint.h",
     "src/core/lib/security/transport/security_connector.h",
+    "src/core/lib/security/transport/tsi_error.h",
     "src/core/lib/security/util/b64.h",
     "src/core/lib/security/util/json_util.h",
     "src/core/lib/tsi/fake_transport_security.h",
@@ -430,6 +431,7 @@
     "src/core/lib/security/transport/secure_endpoint.c",
     "src/core/lib/security/transport/security_connector.c",
     "src/core/lib/security/transport/server_auth_filter.c",
+    "src/core/lib/security/transport/tsi_error.c",
     "src/core/lib/security/util/b64.c",
     "src/core/lib/security/util/json_util.c",
     "src/core/lib/surface/init_secure.c",
@@ -1462,6 +1464,7 @@
     "src/core/lib/security/transport/secure_endpoint.c",
     "src/core/lib/security/transport/security_connector.c",
     "src/core/lib/security/transport/server_auth_filter.c",
+    "src/core/lib/security/transport/tsi_error.c",
     "src/core/lib/security/util/b64.c",
     "src/core/lib/security/util/json_util.c",
     "src/core/lib/surface/init_secure.c",
@@ -1648,6 +1651,7 @@
     "src/core/lib/security/transport/handshake.h",
     "src/core/lib/security/transport/secure_endpoint.h",
     "src/core/lib/security/transport/security_connector.h",
+    "src/core/lib/security/transport/tsi_error.h",
     "src/core/lib/security/util/b64.h",
     "src/core/lib/security/util/json_util.h",
     "src/core/lib/tsi/fake_transport_security.h",
diff --git a/Makefile b/Makefile
index 4410819..6e1c3b6 100644
--- a/Makefile
+++ b/Makefile
@@ -2604,6 +2604,7 @@
     src/core/lib/security/transport/secure_endpoint.c \
     src/core/lib/security/transport/security_connector.c \
     src/core/lib/security/transport/server_auth_filter.c \
+    src/core/lib/security/transport/tsi_error.c \
     src/core/lib/security/util/b64.c \
     src/core/lib/security/util/json_util.c \
     src/core/lib/surface/init_secure.c \
@@ -14348,6 +14349,7 @@
 src/core/lib/security/transport/secure_endpoint.c: $(OPENSSL_DEP)
 src/core/lib/security/transport/security_connector.c: $(OPENSSL_DEP)
 src/core/lib/security/transport/server_auth_filter.c: $(OPENSSL_DEP)
+src/core/lib/security/transport/tsi_error.c: $(OPENSSL_DEP)
 src/core/lib/security/util/b64.c: $(OPENSSL_DEP)
 src/core/lib/security/util/json_util.c: $(OPENSSL_DEP)
 src/core/lib/surface/init_secure.c: $(OPENSSL_DEP)
diff --git a/binding.gyp b/binding.gyp
index 5029f08..3efec93 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -690,6 +690,7 @@
         'src/core/lib/security/transport/secure_endpoint.c',
         'src/core/lib/security/transport/security_connector.c',
         'src/core/lib/security/transport/server_auth_filter.c',
+        'src/core/lib/security/transport/tsi_error.c',
         'src/core/lib/security/util/b64.c',
         'src/core/lib/security/util/json_util.c',
         'src/core/lib/surface/init_secure.c',
diff --git a/build.yaml b/build.yaml
index 4c5d0e9..78c1aaf 100644
--- a/build.yaml
+++ b/build.yaml
@@ -421,6 +421,7 @@
   - src/core/lib/security/transport/handshake.h
   - src/core/lib/security/transport/secure_endpoint.h
   - src/core/lib/security/transport/security_connector.h
+  - src/core/lib/security/transport/tsi_error.h
   - src/core/lib/security/util/b64.h
   - src/core/lib/security/util/json_util.h
   src:
@@ -445,6 +446,7 @@
   - src/core/lib/security/transport/secure_endpoint.c
   - src/core/lib/security/transport/security_connector.c
   - src/core/lib/security/transport/server_auth_filter.c
+  - src/core/lib/security/transport/tsi_error.c
   - src/core/lib/security/util/b64.c
   - src/core/lib/security/util/json_util.c
   - src/core/lib/surface/init_secure.c
diff --git a/config.m4 b/config.m4
index aa6d9fd..7639c4e 100644
--- a/config.m4
+++ b/config.m4
@@ -209,6 +209,7 @@
     src/core/lib/security/transport/secure_endpoint.c \
     src/core/lib/security/transport/security_connector.c \
     src/core/lib/security/transport/server_auth_filter.c \
+    src/core/lib/security/transport/tsi_error.c \
     src/core/lib/security/util/b64.c \
     src/core/lib/security/util/json_util.c \
     src/core/lib/surface/init_secure.c \
diff --git a/gRPC.podspec b/gRPC.podspec
index 84841b8..da147e3 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -274,6 +274,7 @@
                       'src/core/lib/security/transport/handshake.h',
                       'src/core/lib/security/transport/secure_endpoint.h',
                       'src/core/lib/security/transport/security_connector.h',
+                      'src/core/lib/security/transport/tsi_error.h',
                       'src/core/lib/security/util/b64.h',
                       'src/core/lib/security/util/json_util.h',
                       'src/core/lib/tsi/fake_transport_security.h',
@@ -465,6 +466,7 @@
                       'src/core/lib/security/transport/secure_endpoint.c',
                       'src/core/lib/security/transport/security_connector.c',
                       'src/core/lib/security/transport/server_auth_filter.c',
+                      'src/core/lib/security/transport/tsi_error.c',
                       'src/core/lib/security/util/b64.c',
                       'src/core/lib/security/util/json_util.c',
                       'src/core/lib/surface/init_secure.c',
@@ -636,6 +638,7 @@
                               'src/core/lib/security/transport/handshake.h',
                               'src/core/lib/security/transport/secure_endpoint.h',
                               'src/core/lib/security/transport/security_connector.h',
+                              'src/core/lib/security/transport/tsi_error.h',
                               'src/core/lib/security/util/b64.h',
                               'src/core/lib/security/util/json_util.h',
                               'src/core/lib/tsi/fake_transport_security.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 49b2b79..bad5834 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -283,6 +283,7 @@
   s.files += %w( src/core/lib/security/transport/handshake.h )
   s.files += %w( src/core/lib/security/transport/secure_endpoint.h )
   s.files += %w( src/core/lib/security/transport/security_connector.h )
+  s.files += %w( src/core/lib/security/transport/tsi_error.h )
   s.files += %w( src/core/lib/security/util/b64.h )
   s.files += %w( src/core/lib/security/util/json_util.h )
   s.files += %w( src/core/lib/tsi/fake_transport_security.h )
@@ -445,6 +446,7 @@
   s.files += %w( src/core/lib/security/transport/secure_endpoint.c )
   s.files += %w( src/core/lib/security/transport/security_connector.c )
   s.files += %w( src/core/lib/security/transport/server_auth_filter.c )
+  s.files += %w( src/core/lib/security/transport/tsi_error.c )
   s.files += %w( src/core/lib/security/util/b64.c )
   s.files += %w( src/core/lib/security/util/json_util.c )
   s.files += %w( src/core/lib/surface/init_secure.c )
diff --git a/package.xml b/package.xml
index 57e0424..79713e4 100644
--- a/package.xml
+++ b/package.xml
@@ -290,6 +290,7 @@
     <file baseinstalldir="/" name="src/core/lib/security/transport/handshake.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/security_connector.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/util/b64.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/util/json_util.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/tsi/fake_transport_security.h" role="src" />
@@ -452,6 +453,7 @@
     <file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/security_connector.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/transport/server_auth_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/util/b64.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/util/json_util.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/init_secure.c" role="src" />
diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c
index 2c5f9f6..fb8decb 100644
--- a/src/core/lib/iomgr/error.c
+++ b/src/core/lib/iomgr/error.c
@@ -229,6 +229,10 @@
   return new;
 }
 
+const intptr_t *grpc_error_get_int(grpc_error *err, grpc_error_ints which) {
+  return gpr_avl_get(err->ints, (void *)(uintptr_t)which);
+}
+
 grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
                                const char *value) {
   grpc_error *new = copy_error_and_unref(src);
@@ -419,6 +423,13 @@
   return s;
 }
 
+void grpc_error_free_string(const char *str) {
+  if (str == no_error_string) return;
+  if (str == oom_error_string) return;
+  if (str == cancelled_error_string) return;
+  gpr_free((char *)str);
+}
+
 const char *grpc_error_string(grpc_error *err) {
   if (err == GRPC_ERROR_NONE) return no_error_string;
   if (err == GRPC_ERROR_OOM) return oom_error_string;
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 119382c..5d39cef 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -203,6 +203,7 @@
   'src/core/lib/security/transport/secure_endpoint.c',
   'src/core/lib/security/transport/security_connector.c',
   'src/core/lib/security/transport/server_auth_filter.c',
+  'src/core/lib/security/transport/tsi_error.c',
   'src/core/lib/security/util/b64.c',
   'src/core/lib/security/util/json_util.c',
   'src/core/lib/surface/init_secure.c',
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index b133a94..858ebd9 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -186,21 +186,26 @@
 typedef struct addr_req {
   grpc_timer timer;
   char *addr;
-  grpc_resolve_cb cb;
-  void *arg;
+  grpc_closure *on_done;
+  grpc_resolved_addresses **addrs;
 } addr_req;
 
-static void finish_resolve(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
+static void finish_resolve(grpc_exec_ctx *exec_ctx, void *arg,
+                           grpc_error *error) {
   addr_req *r = arg;
 
-  if (success && 0 == strcmp(r->addr, "server")) {
+  if (error == GRPC_ERROR_NONE && 0 == strcmp(r->addr, "server")) {
     grpc_resolved_addresses *addrs = gpr_malloc(sizeof(*addrs));
     addrs->naddrs = 1;
     addrs->addrs = gpr_malloc(sizeof(*addrs->addrs));
     addrs->addrs[0].len = 0;
-    r->cb(exec_ctx, r->arg, addrs);
+    *r->addrs = addrs;
+    grpc_exec_ctx_push(exec_ctx, r->on_done, GRPC_ERROR_NONE, NULL);
   } else {
-    r->cb(exec_ctx, r->arg, NULL);
+    grpc_error_ref(error);
+    grpc_exec_ctx_push(
+        exec_ctx, r->on_done,
+        GRPC_ERROR_CREATE_REFERENCING("Resolution failed", &error, 1), NULL);
   }
 
   gpr_free(r->addr);
@@ -208,12 +213,12 @@
 }
 
 void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
-                        const char *default_port, grpc_resolve_cb cb,
-                        void *arg) {
+                        const char *default_port, grpc_closure *on_done,
+                        grpc_resolved_addresses **addresses) {
   addr_req *r = gpr_malloc(sizeof(*r));
   r->addr = gpr_strdup(addr);
-  r->cb = cb;
-  r->arg = arg;
+  r->on_done = on_done;
+  r->addrs = addresses;
   grpc_timer_init(exec_ctx, &r->timer,
                   gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
                                gpr_time_from_seconds(1, GPR_TIMESPAN)),
@@ -239,11 +244,11 @@
   gpr_timespec deadline;
 } future_connect;
 
-static void do_connect(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
+static void do_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
   future_connect *fc = arg;
-  if (!success) {
+  if (error != GRPC_ERROR_NONE) {
     *fc->ep = NULL;
-    grpc_exec_ctx_enqueue(exec_ctx, fc->closure, false, NULL);
+    grpc_exec_ctx_push(exec_ctx, fc->closure, grpc_error_ref(error), NULL);
   } else if (g_server != NULL) {
     grpc_endpoint *client;
     grpc_endpoint *server;
@@ -255,7 +260,7 @@
     grpc_server_setup_transport(exec_ctx, g_server, transport, NULL);
     grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0);
 
-    grpc_exec_ctx_enqueue(exec_ctx, fc->closure, false, NULL);
+    grpc_exec_ctx_push(exec_ctx, fc->closure, GRPC_ERROR_NONE, NULL);
   } else {
     sched_connect(exec_ctx, fc->closure, fc->ep, fc->deadline);
   }
@@ -266,7 +271,8 @@
                           grpc_endpoint **ep, gpr_timespec deadline) {
   if (gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) < 0) {
     *ep = NULL;
-    grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL);
+    grpc_exec_ctx_push(exec_ctx, closure,
+                       GRPC_ERROR_CREATE("Connect deadline exceeded"), NULL);
     return;
   }
 
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 52082c3..ded76bc 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -128,30 +128,30 @@
 };
 
 static void read_and_write_test_read_handler(grpc_exec_ctx *exec_ctx,
-                                             void *data, bool success) {
+                                             void *data, grpc_error *error) {
   struct read_and_write_test_state *state = data;
 
   state->bytes_read += count_slices(
       state->incoming.slices, state->incoming.count, &state->current_read_data);
-  if (state->bytes_read == state->target_bytes || !success) {
+  if (state->bytes_read == state->target_bytes || error != GRPC_ERROR_NONE) {
     gpr_log(GPR_INFO, "Read handler done");
     gpr_mu_lock(g_mu);
-    state->read_done = 1 + success;
+    state->read_done = 1 + (error == GRPC_ERROR_NONE);
     grpc_pollset_kick(g_pollset, NULL);
     gpr_mu_unlock(g_mu);
-  } else if (success) {
+  } else if (error == GRPC_ERROR_NONE) {
     grpc_endpoint_read(exec_ctx, state->read_ep, &state->incoming,
                        &state->done_read);
   }
 }
 
 static void read_and_write_test_write_handler(grpc_exec_ctx *exec_ctx,
-                                              void *data, bool success) {
+                                              void *data, grpc_error *error) {
   struct read_and_write_test_state *state = data;
   gpr_slice *slices = NULL;
   size_t nslices;
 
-  if (success) {
+  if (error != GRPC_ERROR_NONE) {
     state->bytes_written += state->current_write_size;
     if (state->target_bytes - state->bytes_written <
         state->current_write_size) {
@@ -171,7 +171,7 @@
 
   gpr_log(GPR_INFO, "Write handler done");
   gpr_mu_lock(g_mu);
-  state->write_done = 1 + success;
+  state->write_done = 1 + (error != GRPC_ERROR_NONE);
   grpc_pollset_kick(g_pollset, NULL);
   gpr_mu_unlock(g_mu);
 }
@@ -219,7 +219,7 @@
      for the first iteration as for later iterations. It does the right thing
      even when bytes_written is unsigned. */
   state.bytes_written -= state.current_write_size;
-  read_and_write_test_write_handler(&exec_ctx, &state, 1);
+  read_and_write_test_write_handler(&exec_ctx, &state, GRPC_ERROR_NONE);
   grpc_exec_ctx_finish(&exec_ctx);
 
   grpc_endpoint_read(&exec_ctx, state.read_ep, &state.incoming,
diff --git a/test/core/security/oauth2_utils.c b/test/core/security/oauth2_utils.c
index 80d21cc..e55ce5c 100644
--- a/test/core/security/oauth2_utils.c
+++ b/test/core/security/oauth2_utils.c
@@ -74,7 +74,8 @@
   gpr_mu_unlock(request->mu);
 }
 
-static void do_nothing(grpc_exec_ctx *exec_ctx, void *unused, bool success) {}
+static void do_nothing(grpc_exec_ctx *exec_ctx, void *unused,
+                       grpc_error *error) {}
 
 char *grpc_test_fetch_oauth2_token_with_credentials(
     grpc_call_credentials *creds) {
diff --git a/test/core/util/mock_endpoint.c b/test/core/util/mock_endpoint.c
index 7768413..deef68e 100644
--- a/test/core/util/mock_endpoint.c
+++ b/test/core/util/mock_endpoint.c
@@ -51,7 +51,7 @@
   gpr_mu_lock(&m->mu);
   if (m->read_buffer.count > 0) {
     gpr_slice_buffer_swap(&m->read_buffer, slices);
-    grpc_exec_ctx_enqueue(exec_ctx, cb, true, NULL);
+    grpc_exec_ctx_push(exec_ctx, cb, GRPC_ERROR_NONE, NULL);
   } else {
     m->on_read = cb;
     m->on_read_out = slices;
@@ -65,7 +65,7 @@
   for (size_t i = 0; i < slices->count; i++) {
     m->on_write(slices->slices[i]);
   }
-  grpc_exec_ctx_enqueue(exec_ctx, cb, true, NULL);
+  grpc_exec_ctx_push(exec_ctx, cb, GRPC_ERROR_NONE, NULL);
 }
 
 static void me_add_to_pollset(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
@@ -78,7 +78,8 @@
   grpc_mock_endpoint *m = (grpc_mock_endpoint *)ep;
   gpr_mu_lock(&m->mu);
   if (m->on_read) {
-    grpc_exec_ctx_enqueue(exec_ctx, m->on_read, false, NULL);
+    grpc_exec_ctx_push(exec_ctx, m->on_read,
+                       GRPC_ERROR_CREATE("Endpoint Shutdown"), NULL);
     m->on_read = NULL;
   }
   gpr_mu_unlock(&m->mu);
@@ -115,7 +116,7 @@
   gpr_mu_lock(&m->mu);
   if (m->on_read != NULL) {
     gpr_slice_buffer_add(m->on_read_out, slice);
-    grpc_exec_ctx_enqueue(exec_ctx, m->on_read, true, NULL);
+    grpc_exec_ctx_push(exec_ctx, m->on_read, GRPC_ERROR_NONE, NULL);
     m->on_read = NULL;
   } else {
     gpr_slice_buffer_add(&m->read_buffer, slice);
diff --git a/test/core/util/passthru_endpoint.c b/test/core/util/passthru_endpoint.c
index ae955b1..93753be 100644
--- a/test/core/util/passthru_endpoint.c
+++ b/test/core/util/passthru_endpoint.c
@@ -59,10 +59,11 @@
   half *m = (half *)ep;
   gpr_mu_lock(&m->parent->mu);
   if (m->parent->shutdown) {
-    grpc_exec_ctx_enqueue(exec_ctx, cb, false, NULL);
+    grpc_exec_ctx_push(exec_ctx, cb, GRPC_ERROR_CREATE("Already shutdown"),
+                       NULL);
   } else if (m->read_buffer.count > 0) {
     gpr_slice_buffer_swap(&m->read_buffer, slices);
-    grpc_exec_ctx_enqueue(exec_ctx, cb, true, NULL);
+    grpc_exec_ctx_push(exec_ctx, cb, GRPC_ERROR_NONE, NULL);
   } else {
     m->on_read = cb;
     m->on_read_out = slices;
@@ -79,14 +80,14 @@
                      gpr_slice_buffer *slices, grpc_closure *cb) {
   half *m = other_half((half *)ep);
   gpr_mu_lock(&m->parent->mu);
-  bool ok = true;
+  grpc_error *error = GRPC_ERROR_NONE;
   if (m->parent->shutdown) {
-    ok = false;
+    error = GRPC_ERROR_CREATE("Endpoint already shutdown");
   } else if (m->on_read != NULL) {
     for (size_t i = 0; i < slices->count; i++) {
       gpr_slice_buffer_add(m->on_read_out, gpr_slice_ref(slices->slices[i]));
     }
-    grpc_exec_ctx_enqueue(exec_ctx, m->on_read, true, NULL);
+    grpc_exec_ctx_push(exec_ctx, m->on_read, GRPC_ERROR_NONE, NULL);
     m->on_read = NULL;
   } else {
     for (size_t i = 0; i < slices->count; i++) {
@@ -94,7 +95,7 @@
     }
   }
   gpr_mu_unlock(&m->parent->mu);
-  grpc_exec_ctx_enqueue(exec_ctx, cb, ok, NULL);
+  grpc_exec_ctx_push(exec_ctx, cb, error, NULL);
 }
 
 static void me_add_to_pollset(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
@@ -108,12 +109,14 @@
   gpr_mu_lock(&m->parent->mu);
   m->parent->shutdown = true;
   if (m->on_read) {
-    grpc_exec_ctx_enqueue(exec_ctx, m->on_read, false, NULL);
+    grpc_exec_ctx_push(exec_ctx, m->on_read, GRPC_ERROR_CREATE("Shutdown"),
+                       NULL);
     m->on_read = NULL;
   }
   m = other_half(m);
   if (m->on_read) {
-    grpc_exec_ctx_enqueue(exec_ctx, m->on_read, false, NULL);
+    grpc_exec_ctx_push(exec_ctx, m->on_read, GRPC_ERROR_CREATE("Shutdown"),
+                       NULL);
     m->on_read = NULL;
   }
   gpr_mu_unlock(&m->parent->mu);
diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c
index 84e9054..a03dc0c 100644
--- a/test/core/util/port_server_client.c
+++ b/test/core/util/port_server_client.c
@@ -56,14 +56,14 @@
 } freereq;
 
 static void destroy_pollset_and_shutdown(grpc_exec_ctx *exec_ctx, void *p,
-                                         bool success) {
+                                         grpc_error *error) {
   grpc_pollset_destroy(p);
   gpr_free(p);
   grpc_shutdown();
 }
 
 static void freed_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
-                                   const grpc_httpcli_response *response) {
+                                   grpc_error *error) {
   freereq *pr = arg;
   gpr_mu_lock(pr->mu);
   pr->done = 1;
@@ -74,6 +74,7 @@
 void grpc_free_port_using_server(char *server, int port) {
   grpc_httpcli_context context;
   grpc_httpcli_request req;
+  grpc_httpcli_response rsp;
   freereq pr;
   char *path;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -83,6 +84,7 @@
 
   memset(&pr, 0, sizeof(pr));
   memset(&req, 0, sizeof(req));
+  memset(&rsp, 0, sizeof(rsp));
 
   pr.pollset = gpr_malloc(grpc_pollset_size());
   grpc_pollset_init(pr.pollset, &pr.mu);
@@ -95,8 +97,8 @@
 
   grpc_httpcli_context_init(&context);
   grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
-                   GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), freed_port_from_server,
-                   &pr);
+                   GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
+                   grpc_closure_create(freed_port_from_server, &pr), &rsp);
   gpr_mu_lock(pr.mu);
   while (!pr.done) {
     grpc_pollset_worker *worker = NULL;
@@ -120,19 +122,22 @@
   int retries;
   char *server;
   grpc_httpcli_context *ctx;
+  grpc_httpcli_response response;
 } portreq;
 
 static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
-                                 const grpc_httpcli_response *response) {
+                                 grpc_error *error) {
   size_t i;
   int port = 0;
   portreq *pr = arg;
   int failed = 0;
+  grpc_httpcli_response *response = &pr->response;
 
-  if (!response) {
+  if (error != GRPC_ERROR_NONE) {
     failed = 1;
-    gpr_log(GPR_DEBUG,
-            "failed port pick from server: retrying [response=NULL]");
+    const char *msg = grpc_error_string(error);
+    gpr_log(GPR_DEBUG, "failed port pick from server: retrying [%s]", msg);
+    grpc_error_free_string(msg);
   } else if (response->status != 200) {
     failed = 1;
     gpr_log(GPR_DEBUG, "failed port pick from server: status=%d",
@@ -151,9 +156,12 @@
     pr->retries++;
     req.host = pr->server;
     req.http.path = "/get";
+    grpc_http_response_destroy(&pr->response);
+    memset(&pr->response, 0, sizeof(pr->response));
     grpc_httpcli_get(exec_ctx, pr->ctx, pr->pollset, &req,
-                     GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
-                     pr);
+                     GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
+                     grpc_closure_create(got_port_from_server, pr),
+                     &pr->response);
     return;
   }
   GPR_ASSERT(response);
@@ -193,8 +201,9 @@
 
   grpc_httpcli_context_init(&context);
   grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
-                   GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
-                   &pr);
+                   GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
+                   grpc_closure_create(got_port_from_server, &pr),
+                   &pr.response);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_mu_lock(pr.mu);
   while (pr.port == -1) {
@@ -205,6 +214,7 @@
   }
   gpr_mu_unlock(pr.mu);
 
+  grpc_http_response_destroy(&pr.response);
   grpc_httpcli_context_destroy(&context);
   grpc_pollset_shutdown(&exec_ctx, pr.pollset, shutdown_closure);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index b45e730..39ea15c 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -900,6 +900,7 @@
 src/core/lib/security/transport/handshake.h \
 src/core/lib/security/transport/secure_endpoint.h \
 src/core/lib/security/transport/security_connector.h \
+src/core/lib/security/transport/tsi_error.h \
 src/core/lib/security/util/b64.h \
 src/core/lib/security/util/json_util.h \
 src/core/lib/tsi/fake_transport_security.h \
@@ -1062,6 +1063,7 @@
 src/core/lib/security/transport/secure_endpoint.c \
 src/core/lib/security/transport/security_connector.c \
 src/core/lib/security/transport/server_auth_filter.c \
+src/core/lib/security/transport/tsi_error.c \
 src/core/lib/security/util/b64.c \
 src/core/lib/security/util/json_util.c \
 src/core/lib/surface/init_secure.c \
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 8b521a5..143f78f 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -6035,6 +6035,7 @@
       "src/core/lib/security/transport/handshake.h", 
       "src/core/lib/security/transport/secure_endpoint.h", 
       "src/core/lib/security/transport/security_connector.h", 
+      "src/core/lib/security/transport/tsi_error.h", 
       "src/core/lib/security/util/b64.h", 
       "src/core/lib/security/util/json_util.h"
     ], 
@@ -6080,6 +6081,8 @@
       "src/core/lib/security/transport/security_connector.c", 
       "src/core/lib/security/transport/security_connector.h", 
       "src/core/lib/security/transport/server_auth_filter.c", 
+      "src/core/lib/security/transport/tsi_error.c", 
+      "src/core/lib/security/transport/tsi_error.h", 
       "src/core/lib/security/util/b64.c", 
       "src/core/lib/security/util/b64.h", 
       "src/core/lib/security/util/json_util.c", 
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index d594cd1..331ba04 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -409,6 +409,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\handshake.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\secure_endpoint.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\security_connector.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\util\b64.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\util\json_util.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\fake_transport_security.h" />
@@ -700,6 +701,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\server_auth_filter.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\b64.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\json_util.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index ece040e..a435d79 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -382,6 +382,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\server_auth_filter.c">
       <Filter>src\core\lib\security\transport</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.c">
+      <Filter>src\core\lib\security\transport</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\b64.c">
       <Filter>src\core\lib\security\util</Filter>
     </ClCompile>
@@ -947,6 +950,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\security_connector.h">
       <Filter>src\core\lib\security\transport</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.h">
+      <Filter>src\core\lib\security\transport</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\util\b64.h">
       <Filter>src\core\lib\security\util</Filter>
     </ClInclude>