Merge pull request #10109 from ncteisen/error-slice-optimization

Error slice optimization
diff --git a/doc/core/grpc-error.md b/doc/core/grpc-error.md
index 1fa2480..c05d1dd 100644
--- a/doc/core/grpc-error.md
+++ b/doc/core/grpc-error.md
@@ -56,7 +56,7 @@
 current function.
 
 ```C
-grpc_error* error1 = GRPC_ERROR_CREATE("Some error occured");
+grpc_error* error1 = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
 grpc_error* error2 = some_operation_that_might_fail(...);
 ```
 
@@ -87,7 +87,7 @@
 not callbacks, so they will take ownership of the error passed to them.
 
 ```C
-grpc_error* error = GRPC_ERROR_CREATE("Some error occured");
+grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
 grpc_closure_run(exec_ctx, cb, error);
 // current function no longer has ownership of the error
 ```
@@ -96,7 +96,7 @@
 you must explicitly take a reference.
 
 ```C
-grpc_error* error = GRPC_ERROR_CREATE("Some error occured");
+grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
 grpc_closure_run(exec_ctx, cb, GRPC_ERROR_REF(error));
 // do some other things with the error
 GRPC_ERROR_UNREF(error);
@@ -128,7 +128,7 @@
 Take the following example:
 
 ```C
-grpc_error* error = GRPC_ERROR_CREATE("Some error occured");
+grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
 // do some things
 some_function(error);
 // can't use error anymore! might be gone.
@@ -142,7 +142,7 @@
 
 ```C
 void func() {
-  grpc_error* error = GRPC_ERROR_CREATE("Some error occured");
+  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error");
   some_function(GRPC_ERROR_REF(error));
   // do things
   some_other_function(GRPC_ERROR_REF(error));
diff --git a/src/core/ext/client_channel/channel_connectivity.c b/src/core/ext/client_channel/channel_connectivity.c
index dd70bc2..f6cb3b9 100644
--- a/src/core/ext/client_channel/channel_connectivity.c
+++ b/src/core/ext/client_channel/channel_connectivity.c
@@ -139,8 +139,8 @@
     error = GRPC_ERROR_NONE;
   } else {
     if (error == GRPC_ERROR_NONE) {
-      error =
-          GRPC_ERROR_CREATE("Timed out waiting for connection state change");
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "Timed out waiting for connection state change");
     } else if (error == GRPC_ERROR_CANCELLED) {
       error = GRPC_ERROR_NONE;
     }
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index 00c2091..435a3ab 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -355,7 +355,8 @@
   grpc_slice_hash_table *method_params_table = NULL;
   grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE;
   bool exit_idle = false;
-  grpc_error *state_error = GRPC_ERROR_CREATE("No load balancing policy");
+  grpc_error *state_error =
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy");
   char *service_config_json = NULL;
   service_config_parsing_state parsing_state;
   memset(&parsing_state, 0, sizeof(parsing_state));
@@ -475,9 +476,9 @@
   if (lb_policy != NULL) {
     grpc_closure_list_sched(exec_ctx, &chand->waiting_for_config_closures);
   } else if (chand->resolver == NULL /* disconnected */) {
-    grpc_closure_list_fail_all(
-        &chand->waiting_for_config_closures,
-        GRPC_ERROR_CREATE_REFERENCING("Channel disconnected", &error, 1));
+    grpc_closure_list_fail_all(&chand->waiting_for_config_closures,
+                               GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                                   "Channel disconnected", &error, 1));
     grpc_closure_list_sched(exec_ctx, &chand->waiting_for_config_closures);
   }
   if (lb_policy != NULL && chand->exit_idle_when_lb_policy_arrives) {
@@ -505,8 +506,8 @@
     grpc_error *refs[] = {error, state_error};
     set_channel_connectivity_state_locked(
         exec_ctx, chand, GRPC_CHANNEL_SHUTDOWN,
-        GRPC_ERROR_CREATE_REFERENCING("Got config after disconnection", refs,
-                                      GPR_ARRAY_SIZE(refs)),
+        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+            "Got config after disconnection", refs, GPR_ARRAY_SIZE(refs)),
         "resolver_gone");
   }
 
@@ -545,8 +546,9 @@
 
   if (op->send_ping != NULL) {
     if (chand->lb_policy == NULL) {
-      grpc_closure_sched(exec_ctx, op->send_ping,
-                         GRPC_ERROR_CREATE("Ping with no load balancing"));
+      grpc_closure_sched(
+          exec_ctx, op->send_ping,
+          GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"));
     } else {
       grpc_lb_policy_ping_one_locked(exec_ctx, chand->lb_policy, op->send_ping);
       op->bind_pollset = NULL;
@@ -661,7 +663,7 @@
   if (proxy_name != NULL) gpr_free(proxy_name);
   if (new_args != NULL) grpc_channel_args_destroy(exec_ctx, new_args);
   if (chand->resolver == NULL) {
-    return GRPC_ERROR_CREATE("resolver creation failed");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed");
   }
   return GRPC_ERROR_NONE;
 }
@@ -874,12 +876,14 @@
   calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
   if (calld->connected_subchannel == NULL) {
     gpr_atm_no_barrier_store(&calld->subchannel_call, 1);
-    fail_locked(exec_ctx, calld, GRPC_ERROR_CREATE_REFERENCING(
-                                     "Failed to create subchannel", &error, 1));
+    fail_locked(exec_ctx, calld,
+                GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                    "Failed to create subchannel", &error, 1));
   } else if (GET_CALL(calld) == CANCELLED_CALL) {
     /* already cancelled before subchannel became ready */
-    grpc_error *cancellation_error = GRPC_ERROR_CREATE_REFERENCING(
-        "Cancelled before creating subchannel", &error, 1);
+    grpc_error *cancellation_error =
+        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+            "Cancelled before creating subchannel", &error, 1);
     /* if due to deadline, attach the deadline exceeded status to the error */
     if (gpr_time_cmp(calld->deadline, gpr_now(GPR_CLOCK_MONOTONIC)) < 0) {
       cancellation_error =
@@ -981,9 +985,9 @@
       cpa = closure->cb_arg;
       if (cpa->connected_subchannel == connected_subchannel) {
         cpa->connected_subchannel = NULL;
-        grpc_closure_sched(
-            exec_ctx, cpa->on_ready,
-            GRPC_ERROR_CREATE_REFERENCING("Pick cancelled", &error, 1));
+        grpc_closure_sched(exec_ctx, cpa->on_ready,
+                           GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                               "Pick cancelled", &error, 1));
       }
     }
     GPR_TIMER_END("pick_subchannel", 0);
@@ -1040,7 +1044,8 @@
     grpc_closure_list_append(&chand->waiting_for_config_closures, &cpa->closure,
                              GRPC_ERROR_NONE);
   } else {
-    grpc_closure_sched(exec_ctx, on_ready, GRPC_ERROR_CREATE("Disconnected"));
+    grpc_closure_sched(exec_ctx, on_ready,
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected"));
   }
 
   GPR_TIMER_END("pick_subchannel", 0);
diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index 58ab233..778d76c 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -116,7 +116,7 @@
     // If we were shut down after an endpoint operation succeeded but
     // before the endpoint callback was invoked, we need to generate our
     // own error.
-    error = GRPC_ERROR_CREATE("Handshaker shutdown");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshaker shutdown");
   }
   if (!handshaker->shutdown) {
     // TODO(ctiller): It is currently necessary to shutdown endpoints
@@ -226,7 +226,7 @@
     char* msg;
     gpr_asprintf(&msg, "HTTP proxy returned response code %d",
                  handshaker->http_response.status);
-    error = GRPC_ERROR_CREATE(msg);
+    error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     handshake_failed_locked(exec_ctx, handshaker, error);
     goto done;
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index e886fbc..063c0ba 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -269,8 +269,9 @@
   gpr_mu_lock(&c->mu);
   GPR_ASSERT(!c->disconnected);
   c->disconnected = true;
-  grpc_connector_shutdown(exec_ctx, c->connector,
-                          GRPC_ERROR_CREATE("Subchannel disconnected"));
+  grpc_connector_shutdown(
+      exec_ctx, c->connector,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Subchannel disconnected"));
   con = GET_CONNECTED_SUBCHANNEL(c, no_barrier);
   if (con != NULL) {
     GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, con, "connection");
@@ -437,7 +438,8 @@
   gpr_mu_lock(&c->mu);
   c->have_alarm = false;
   if (c->disconnected) {
-    error = GRPC_ERROR_CREATE_REFERENCING("Disconnected", &error, 1);
+    error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected",
+                                                             &error, 1);
   } else {
     GRPC_ERROR_REF(error);
   }
@@ -688,9 +690,9 @@
   } else {
     grpc_connectivity_state_set(
         exec_ctx, &c->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
-        grpc_error_set_int(
-            GRPC_ERROR_CREATE_REFERENCING("Connect Failed", &error, 1),
-            GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
+        grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                               "Connect Failed", &error, 1),
+                           GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
         "connect_failed");
 
     const char *errmsg = grpc_error_string(error);
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index d612591..601b0e6 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -925,7 +925,7 @@
   }
   grpc_connectivity_state_set(
       exec_ctx, &glb_policy->state_tracker, GRPC_CHANNEL_SHUTDOWN,
-      GRPC_ERROR_CREATE("Channel Shutdown"), "glb_shutdown");
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel Shutdown"), "glb_shutdown");
   /* We need a copy of the lb_call pointer because we can't cancell the call
    * while holding glb_policy->mu: lb_on_server_status_received, invoked due to
    * the cancel, needs to acquire that same lock */
@@ -965,9 +965,9 @@
     pending_pick *next = pp->next;
     if (pp->target == target) {
       *target = NULL;
-      grpc_closure_sched(
-          exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
-          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1));
+      grpc_closure_sched(exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
+                         GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Pick Cancelled", &error, 1));
     } else {
       pp->next = glb_policy->pending_picks;
       glb_policy->pending_picks = pp;
@@ -989,9 +989,9 @@
     pending_pick *next = pp->next;
     if ((pp->pick_args.initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
-      grpc_closure_sched(
-          exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
-          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1));
+      grpc_closure_sched(exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
+                         GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Pick Cancelled", &error, 1));
     } else {
       pp->next = glb_policy->pending_picks;
       glb_policy->pending_picks = pp;
@@ -1023,10 +1023,10 @@
                            grpc_closure *on_complete) {
   if (pick_args->lb_token_mdelem_storage == NULL) {
     *target = NULL;
-    grpc_closure_sched(
-        exec_ctx, on_complete,
-        GRPC_ERROR_CREATE("No mdelem storage for the LB token. Load reporting "
-                          "won't work without it. Failing"));
+    grpc_closure_sched(exec_ctx, on_complete,
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                           "No mdelem storage for the LB token. Load reporting "
+                           "won't work without it. Failing"));
     return 0;
   }
 
diff --git a/src/core/ext/lb_policy/pick_first/pick_first.c b/src/core/ext/lb_policy/pick_first/pick_first.c
index 179dcd6..fc65dfd 100644
--- a/src/core/ext/lb_policy/pick_first/pick_first.c
+++ b/src/core/ext/lb_policy/pick_first/pick_first.c
@@ -101,7 +101,7 @@
   p->pending_picks = NULL;
   grpc_connectivity_state_set(
       exec_ctx, &p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
-      GRPC_ERROR_CREATE("Channel shutdown"), "shutdown");
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"), "shutdown");
   /* cancel subscription */
   if (p->selected != NULL) {
     grpc_connected_subchannel_notify_on_state_change(
@@ -131,9 +131,9 @@
     pending_pick *next = pp->next;
     if (pp->target == target) {
       *target = NULL;
-      grpc_closure_sched(
-          exec_ctx, pp->on_complete,
-          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1));
+      grpc_closure_sched(exec_ctx, pp->on_complete,
+                         GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Pick Cancelled", &error, 1));
       gpr_free(pp);
     } else {
       pp->next = p->pending_picks;
@@ -156,9 +156,9 @@
     pending_pick *next = pp->next;
     if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
-      grpc_closure_sched(
-          exec_ctx, pp->on_complete,
-          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1));
+      grpc_closure_sched(exec_ctx, pp->on_complete,
+                         GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Pick Cancelled", &error, 1));
       gpr_free(pp);
     } else {
       pp->next = p->pending_picks;
@@ -325,8 +325,8 @@
         if (p->num_subchannels == 0) {
           grpc_connectivity_state_set(
               exec_ctx, &p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
-              GRPC_ERROR_CREATE_REFERENCING("Pick first exhausted channels",
-                                            &error, 1),
+              GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                  "Pick first exhausted channels", &error, 1),
               "no_more_channels");
           while ((pp = p->pending_picks)) {
             p->pending_picks = pp->next;
@@ -373,7 +373,8 @@
   if (p->selected) {
     grpc_connected_subchannel_ping(exec_ctx, p->selected, closure);
   } else {
-    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE("Not connected"));
+    grpc_closure_sched(exec_ctx, closure,
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING("Not connected"));
   }
 }
 
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c
index 09562d3..a62082a 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -320,13 +320,14 @@
   while ((pp = p->pending_picks)) {
     p->pending_picks = pp->next;
     *pp->target = NULL;
-    grpc_closure_sched(exec_ctx, pp->on_complete,
-                       GRPC_ERROR_CREATE("Channel Shutdown"));
+    grpc_closure_sched(
+        exec_ctx, pp->on_complete,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel Shutdown"));
     gpr_free(pp);
   }
   grpc_connectivity_state_set(
       exec_ctx, &p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
-      GRPC_ERROR_CREATE("Channel Shutdown"), "rr_shutdown");
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel Shutdown"), "rr_shutdown");
   for (i = 0; i < p->num_subchannels; i++) {
     subchannel_data *sd = p->subchannels[i];
     grpc_subchannel_notify_on_state_change(exec_ctx, sd->subchannel, NULL, NULL,
@@ -345,9 +346,9 @@
     pending_pick *next = pp->next;
     if (pp->target == target) {
       *target = NULL;
-      grpc_closure_sched(
-          exec_ctx, pp->on_complete,
-          GRPC_ERROR_CREATE_REFERENCING("Pick cancelled", &error, 1));
+      grpc_closure_sched(exec_ctx, pp->on_complete,
+                         GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Pick cancelled", &error, 1));
       gpr_free(pp);
     } else {
       pp->next = p->pending_picks;
@@ -371,9 +372,9 @@
     if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
       *pp->target = NULL;
-      grpc_closure_sched(
-          exec_ctx, pp->on_complete,
-          GRPC_ERROR_CREATE_REFERENCING("Pick cancelled", &error, 1));
+      grpc_closure_sched(exec_ctx, pp->on_complete,
+                         GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Pick cancelled", &error, 1));
       gpr_free(pp);
     } else {
       pp->next = p->pending_picks;
@@ -661,8 +662,8 @@
     grpc_connected_subchannel_ping(exec_ctx, target, closure);
     GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, target, "rr_picked");
   } else {
-    grpc_closure_sched(exec_ctx, closure,
-                       GRPC_ERROR_CREATE("Round Robin not connected"));
+    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                              "Round Robin not connected"));
   }
 }
 
diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c
index 4ed8326..ea57c85 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.c
+++ b/src/core/ext/load_reporting/load_reporting_filter.c
@@ -78,8 +78,8 @@
           GRPC_MDVALUE(calld->recv_initial_metadata->idx.named.path->md));
       calld->have_service_method = true;
     } else {
-      err =
-          grpc_error_add_child(err, GRPC_ERROR_CREATE("Missing :path header"));
+      err = grpc_error_add_child(
+          err, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing :path header"));
     }
     if (calld->recv_initial_metadata->idx.named.lb_token != NULL) {
       calld->initial_md_string = grpc_slice_ref_internal(
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index d227c19..d6cb6a9 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -113,8 +113,9 @@
   }
   if (r->next_completion != NULL) {
     *r->target_result = NULL;
-    grpc_closure_sched(exec_ctx, r->next_completion,
-                       GRPC_ERROR_CREATE("Resolver Shutdown"));
+    grpc_closure_sched(
+        exec_ctx, r->next_completion,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver Shutdown"));
     r->next_completion = NULL;
   }
 }
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c
index d49c32b..2b226c1 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.c
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c
@@ -113,7 +113,7 @@
   gpr_mu_lock(&c->mu);
   if (error != GRPC_ERROR_NONE || c->shutdown) {
     if (error == GRPC_ERROR_NONE) {
-      error = GRPC_ERROR_CREATE("connector shutdown");
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("connector shutdown");
       // We were shut down after handshaking completed successfully, so
       // destroy the endpoint here.
       // TODO(ctiller): It is currently necessary to shutdown endpoints
@@ -164,7 +164,7 @@
   c->connecting = false;
   if (error != GRPC_ERROR_NONE || c->shutdown) {
     if (error == GRPC_ERROR_NONE) {
-      error = GRPC_ERROR_CREATE("connector shutdown");
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("connector shutdown");
     } else {
       error = GRPC_ERROR_REF(error);
     }
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.c b/src/core/ext/transport/chttp2/server/chttp2_server.c
index 837b9fd..6433968 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.c
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.c
@@ -256,7 +256,7 @@
     char *msg;
     gpr_asprintf(&msg, "No address added out of total %" PRIuPTR " resolved",
                  naddrs);
-    err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, naddrs);
+    err = GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(msg, errors, naddrs);
     gpr_free(msg);
     goto error;
   } else if (count != naddrs) {
@@ -264,7 +264,7 @@
     gpr_asprintf(&msg, "Only %" PRIuPTR
                        " addresses added out of total %" PRIuPTR " resolved",
                  count, naddrs);
-    err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, naddrs);
+    err = GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(msg, errors, naddrs);
     gpr_free(msg);
 
     const char *warning_message = grpc_error_string(err);
diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
index cb2b3f5..88c813f 100644
--- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
@@ -61,7 +61,7 @@
       3, (server, addr, creds));
   // Create security context.
   if (creds == NULL) {
-    err = GRPC_ERROR_CREATE(
+    err = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
         "No credentials specified for secure server port (creds==NULL)");
     goto done;
   }
@@ -72,7 +72,7 @@
     gpr_asprintf(&msg,
                  "Unable to create secure server with credentials of type %s.",
                  creds->type);
-    err = grpc_error_set_int(GRPC_ERROR_CREATE(msg),
+    err = grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg),
                              GRPC_ERROR_INT_SECURITY_STATUS, status);
     gpr_free(msg);
     goto done;
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 89659e7..88d96b1 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -187,7 +187,8 @@
 
   GRPC_COMBINER_UNREF(exec_ctx, t->combiner, "chttp2_transport");
 
-  cancel_pings(exec_ctx, t, GRPC_ERROR_CREATE("Transport destroyed"));
+  cancel_pings(exec_ctx, t,
+               GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"));
 
   while (t->write_cb_pool) {
     grpc_chttp2_write_cb *next = t->write_cb_pool->next;
@@ -494,8 +495,9 @@
   t->destroying = 1;
   close_transport_locked(
       exec_ctx, t,
-      grpc_error_set_int(GRPC_ERROR_CREATE("Transport destroyed"),
-                         GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state));
+      grpc_error_set_int(
+          GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"),
+          GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state));
   GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "destroy");
 }
 
@@ -518,7 +520,8 @@
     if (t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE) {
       if (t->close_transport_on_writes_finished == NULL) {
         t->close_transport_on_writes_finished =
-            GRPC_ERROR_CREATE("Delayed close due to in-progress write");
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                "Delayed close due to in-progress write");
       }
       t->close_transport_on_writes_finished =
           grpc_error_add_child(t->close_transport_on_writes_finished, error);
@@ -834,7 +837,8 @@
   if (t->sent_goaway_state == GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED) {
     t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SENT;
     if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) {
-      close_transport_locked(exec_ctx, t, GRPC_ERROR_CREATE("goaway sent"));
+      close_transport_locked(
+          exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING("goaway sent"));
     }
   }
 
@@ -898,22 +902,19 @@
                                      grpc_chttp2_transport *t,
                                      uint32_t goaway_error,
                                      grpc_slice goaway_text) {
-  char *msg = grpc_dump_slice(goaway_text, GPR_DUMP_HEX | GPR_DUMP_ASCII);
-  GRPC_CHTTP2_IF_TRACING(
-      gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg));
-  grpc_slice_unref_internal(exec_ctx, goaway_text);
+  // GRPC_CHTTP2_IF_TRACING(
+  //     gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg));
   t->seen_goaway = 1;
   /* lie: use transient failure from the transport to indicate goaway has been
    * received */
   connectivity_state_set(
       exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE,
       grpc_error_set_str(
-          grpc_error_set_int(GRPC_ERROR_CREATE("GOAWAY received"),
-                             GRPC_ERROR_INT_HTTP2_ERROR,
-                             (intptr_t)goaway_error),
-          GRPC_ERROR_STR_RAW_BYTES, msg),
+          grpc_error_set_int(
+              GRPC_ERROR_CREATE_FROM_STATIC_STRING("GOAWAY received"),
+              GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)goaway_error),
+          GRPC_ERROR_STR_RAW_BYTES, goaway_text),
       "got_goaway");
-  gpr_free(msg);
 }
 
 static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx,
@@ -936,9 +937,10 @@
     t->next_stream_id += 2;
 
     if (t->next_stream_id >= MAX_CLIENT_STREAM_ID) {
-      connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE,
-                             GRPC_ERROR_CREATE("Stream IDs exhausted"),
-                             "no_more_stream_ids");
+      connectivity_state_set(
+          exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE,
+          GRPC_ERROR_CREATE_FROM_STATIC_STRING("Stream IDs exhausted"),
+          "no_more_stream_ids");
     }
 
     grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
@@ -952,9 +954,9 @@
          grpc_chttp2_list_pop_waiting_for_concurrency(t, &s)) {
     grpc_chttp2_cancel_stream(
         exec_ctx, t, s,
-        grpc_error_set_int(GRPC_ERROR_CREATE("Stream IDs exhausted"),
-                           GRPC_ERROR_INT_GRPC_STATUS,
-                           GRPC_STATUS_UNAVAILABLE));
+        grpc_error_set_int(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Stream IDs exhausted"),
+            GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE));
   }
 }
 
@@ -1003,11 +1005,11 @@
   }
   if (error != GRPC_ERROR_NONE) {
     if (closure->error_data.error == GRPC_ERROR_NONE) {
-      closure->error_data.error =
-          GRPC_ERROR_CREATE("Error in HTTP transport completing operation");
-      closure->error_data.error =
-          grpc_error_set_str(closure->error_data.error,
-                             GRPC_ERROR_STR_TARGET_ADDRESS, t->peer_string);
+      closure->error_data.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "Error in HTTP transport completing operation");
+      closure->error_data.error = grpc_error_set_str(
+          closure->error_data.error, GRPC_ERROR_STR_TARGET_ADDRESS,
+          grpc_slice_from_copied_string(t->peer_string));
     }
     closure->error_data.error =
         grpc_error_add_child(closure->error_data.error, error);
@@ -1182,10 +1184,11 @@
           exec_ctx, t, s,
           grpc_error_set_int(
               grpc_error_set_int(
-                  grpc_error_set_int(
-                      GRPC_ERROR_CREATE("to-be-sent initial metadata size "
-                                        "exceeds peer limit"),
-                      GRPC_ERROR_INT_SIZE, (intptr_t)metadata_size),
+                  grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                         "to-be-sent initial metadata size "
+                                         "exceeds peer limit"),
+                                     GRPC_ERROR_INT_SIZE,
+                                     (intptr_t)metadata_size),
                   GRPC_ERROR_INT_LIMIT, (intptr_t)metadata_peer_limit),
               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
     } else {
@@ -1201,9 +1204,9 @@
           } else {
             grpc_chttp2_cancel_stream(
                 exec_ctx, t, s,
-                grpc_error_set_int(GRPC_ERROR_CREATE("Transport closed"),
-                                   GRPC_ERROR_INT_GRPC_STATUS,
-                                   GRPC_STATUS_UNAVAILABLE));
+                grpc_error_set_int(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport closed"),
+                    GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE));
           }
         } else {
           GPR_ASSERT(s->id != 0);
@@ -1215,7 +1218,7 @@
         s->send_initial_metadata = NULL;
         grpc_chttp2_complete_closure_step(
             exec_ctx, t, s, &s->send_initial_metadata_finished,
-            GRPC_ERROR_CREATE_REFERENCING(
+            GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
                 "Attempt to send initial metadata after stream was closed",
                 &s->write_closed_error, 1),
             "send_initial_metadata_finished");
@@ -1229,7 +1232,7 @@
     if (s->write_closed) {
       grpc_chttp2_complete_closure_step(
           exec_ctx, t, s, &s->fetching_send_message_finished,
-          GRPC_ERROR_CREATE_REFERENCING(
+          GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
               "Attempt to send message after stream was closed",
               &s->write_closed_error, 1),
           "fetching_send_message_finished");
@@ -1277,10 +1280,11 @@
           exec_ctx, t, s,
           grpc_error_set_int(
               grpc_error_set_int(
-                  grpc_error_set_int(
-                      GRPC_ERROR_CREATE("to-be-sent trailing metadata size "
-                                        "exceeds peer limit"),
-                      GRPC_ERROR_INT_SIZE, (intptr_t)metadata_size),
+                  grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                         "to-be-sent trailing metadata size "
+                                         "exceeds peer limit"),
+                                     GRPC_ERROR_INT_SIZE,
+                                     (intptr_t)metadata_size),
                   GRPC_ERROR_INT_LIMIT, (intptr_t)metadata_peer_limit),
               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
     } else {
@@ -1293,8 +1297,9 @@
             exec_ctx, t, s, &s->send_trailing_metadata_finished,
             grpc_metadata_batch_is_empty(op->send_trailing_metadata)
                 ? GRPC_ERROR_NONE
-                : GRPC_ERROR_CREATE("Attempt to send trailing metadata after "
-                                    "stream was closed"),
+                : GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                      "Attempt to send trailing metadata after "
+                      "stream was closed"),
             "send_trailing_metadata_finished");
       } else if (s->id != 0) {
         /* TODO(ctiller): check if there's flow control for any outstanding
@@ -1409,11 +1414,11 @@
                         grpc_error *error) {
   t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED;
   grpc_http2_error_code http_error;
-  const char *msg;
-  grpc_error_get_status(error, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL, &msg,
-                        &http_error);
+  grpc_slice slice;
+  grpc_error_get_status(error, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL,
+                        &slice, &http_error);
   grpc_chttp2_goaway_append(t->last_new_stream_id, (uint32_t)http_error,
-                            grpc_slice_from_copied_string(msg), &t->qbuf);
+                            grpc_slice_ref_internal(slice), &t->qbuf);
   grpc_chttp2_initiate_write(exec_ctx, t, false, "goaway_sent");
   GRPC_ERROR_UNREF(error);
 }
@@ -1573,7 +1578,7 @@
     if (t->sent_goaway_state == GRPC_CHTTP2_GOAWAY_SENT) {
       close_transport_locked(
           exec_ctx, t,
-          GRPC_ERROR_CREATE_REFERENCING(
+          GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
               "Last stream closed after sending GOAWAY", &error, 1));
     }
   }
@@ -1614,8 +1619,8 @@
 void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                              grpc_chttp2_stream *s, grpc_error *error) {
   grpc_status_code status;
-  const char *msg;
-  grpc_error_get_status(error, s->deadline, &status, &msg, NULL);
+  grpc_slice slice;
+  grpc_error_get_status(error, s->deadline, &status, &slice, NULL);
 
   if (status != GRPC_STATUS_OK) {
     s->seen_error = true;
@@ -1636,13 +1641,13 @@
                           grpc_mdelem_from_slices(
                               exec_ctx, GRPC_MDSTR_GRPC_STATUS,
                               grpc_slice_from_copied_string(status_string))));
-    if (msg != NULL) {
+    if (!GRPC_SLICE_IS_EMPTY(slice)) {
       GRPC_LOG_IF_ERROR(
           "add_status_message",
           grpc_chttp2_incoming_metadata_buffer_replace_or_add(
               exec_ctx, &s->metadata_buffer[1],
               grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
-                                      grpc_slice_from_copied_string(msg))));
+                                      grpc_slice_ref_internal(slice))));
     }
     s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE;
     grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
@@ -1671,7 +1676,8 @@
   add_error(extra_error, refs, &nrefs);
   grpc_error *error = GRPC_ERROR_NONE;
   if (nrefs > 0) {
-    error = GRPC_ERROR_CREATE_REFERENCING(master_error_msg, refs, nrefs);
+    error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(master_error_msg,
+                                                             refs, nrefs);
   }
   GRPC_ERROR_UNREF(extra_error);
   return error;
@@ -1770,8 +1776,8 @@
   uint8_t *p;
   uint32_t len = 0;
   grpc_status_code grpc_status;
-  const char *msg;
-  grpc_error_get_status(error, s->deadline, &grpc_status, &msg, NULL);
+  grpc_slice slice;
+  grpc_error_get_status(error, s->deadline, &grpc_status, &slice, NULL);
 
   GPR_ASSERT(grpc_status >= 0 && (int)grpc_status < 100);
 
@@ -1827,32 +1833,30 @@
   GPR_ASSERT(p == GRPC_SLICE_END_PTR(status_hdr));
   len += (uint32_t)GRPC_SLICE_LENGTH(status_hdr);
 
-  if (msg != NULL) {
-    size_t msg_len = strlen(msg);
-    GPR_ASSERT(msg_len <= UINT32_MAX);
-    uint32_t msg_len_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)msg_len, 0);
-    message_pfx = grpc_slice_malloc(14 + msg_len_len);
-    p = GRPC_SLICE_START_PTR(message_pfx);
-    *p++ = 0x00; /* literal header, not indexed */
-    *p++ = 12;   /* len(grpc-message) */
-    *p++ = 'g';
-    *p++ = 'r';
-    *p++ = 'p';
-    *p++ = 'c';
-    *p++ = '-';
-    *p++ = 'm';
-    *p++ = 'e';
-    *p++ = 's';
-    *p++ = 's';
-    *p++ = 'a';
-    *p++ = 'g';
-    *p++ = 'e';
-    GRPC_CHTTP2_WRITE_VARINT((uint32_t)msg_len, 0, 0, p, (uint32_t)msg_len_len);
-    p += msg_len_len;
-    GPR_ASSERT(p == GRPC_SLICE_END_PTR(message_pfx));
-    len += (uint32_t)GRPC_SLICE_LENGTH(message_pfx);
-    len += (uint32_t)msg_len;
-  }
+  size_t msg_len = GRPC_SLICE_LENGTH(slice);
+  GPR_ASSERT(msg_len <= UINT32_MAX);
+  uint32_t msg_len_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)msg_len, 0);
+  message_pfx = grpc_slice_malloc(14 + msg_len_len);
+  p = GRPC_SLICE_START_PTR(message_pfx);
+  *p++ = 0x00; /* literal header, not indexed */
+  *p++ = 12;   /* len(grpc-message) */
+  *p++ = 'g';
+  *p++ = 'r';
+  *p++ = 'p';
+  *p++ = 'c';
+  *p++ = '-';
+  *p++ = 'm';
+  *p++ = 'e';
+  *p++ = 's';
+  *p++ = 's';
+  *p++ = 'a';
+  *p++ = 'g';
+  *p++ = 'e';
+  GRPC_CHTTP2_WRITE_VARINT((uint32_t)msg_len, 0, 0, p, (uint32_t)msg_len_len);
+  p += msg_len_len;
+  GPR_ASSERT(p == GRPC_SLICE_END_PTR(message_pfx));
+  len += (uint32_t)GRPC_SLICE_LENGTH(message_pfx);
+  len += (uint32_t)msg_len;
 
   hdr = grpc_slice_malloc(9);
   p = GRPC_SLICE_START_PTR(hdr);
@@ -1872,10 +1876,8 @@
     grpc_slice_buffer_add(&t->qbuf, http_status_hdr);
   }
   grpc_slice_buffer_add(&t->qbuf, status_hdr);
-  if (msg != NULL) {
-    grpc_slice_buffer_add(&t->qbuf, message_pfx);
-    grpc_slice_buffer_add(&t->qbuf, grpc_slice_from_copied_string(msg));
-  }
+  grpc_slice_buffer_add(&t->qbuf, message_pfx);
+  grpc_slice_buffer_add(&t->qbuf, grpc_slice_ref_internal(slice));
   grpc_slice_buffer_add(
       &t->qbuf, grpc_chttp2_rst_stream_create(s->id, GRPC_HTTP2_NO_ERROR,
                                               &s->stats.outgoing));
@@ -1950,9 +1952,9 @@
   if (parse_error == GRPC_ERROR_NONE &&
       (parse_error = grpc_http_parser_eof(&parser)) == GRPC_ERROR_NONE) {
     error = grpc_error_set_int(
-        grpc_error_set_int(
-            GRPC_ERROR_CREATE("Trying to connect an http1.x server"),
-            GRPC_ERROR_INT_HTTP_STATUS, response.status),
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                               "Trying to connect an http1.x server"),
+                           GRPC_ERROR_INT_HTTP_STATUS, response.status),
         GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
   }
   GRPC_ERROR_UNREF(parse_error);
@@ -1973,9 +1975,10 @@
 
   grpc_error *err = error;
   if (err != GRPC_ERROR_NONE) {
-    err = grpc_error_set_int(
-        GRPC_ERROR_CREATE_REFERENCING("Endpoint read failed", &err, 1),
-        GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state);
+    err = grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                                 "Endpoint read failed", &err, 1),
+                             GRPC_ERROR_INT_OCCURRED_DURING_WRITE,
+                             t->write_state);
   }
   GPR_SWAP(grpc_error *, err, error);
   GRPC_ERROR_UNREF(err);
@@ -1996,8 +1999,8 @@
     if (errors[1] != GRPC_ERROR_NONE) {
       errors[2] = try_http_parsing(exec_ctx, t);
       GRPC_ERROR_UNREF(error);
-      error = GRPC_ERROR_CREATE_REFERENCING("Failed parsing HTTP/2", errors,
-                                            GPR_ARRAY_SIZE(errors));
+      error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+          "Failed parsing HTTP/2", errors, GPR_ARRAY_SIZE(errors));
     }
     for (i = 0; i < GPR_ARRAY_SIZE(errors); i++) {
       GRPC_ERROR_UNREF(errors[i]);
@@ -2022,7 +2025,7 @@
   GPR_TIMER_BEGIN("post_reading_action_locked", 0);
   bool keep_reading = false;
   if (error == GRPC_ERROR_NONE && t->closed) {
-    error = GRPC_ERROR_CREATE("Transport closed");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport closed");
   }
   if (error != GRPC_ERROR_NONE) {
     close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error));
@@ -2157,8 +2160,8 @@
   if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) {
     if (error == GRPC_ERROR_NONE) {
       t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING;
-      close_transport_locked(exec_ctx, t,
-                             GRPC_ERROR_CREATE("keepalive watchdog timeout"));
+      close_transport_locked(exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                              "keepalive watchdog timeout"));
     }
   } else {
     /** The watchdog timer should have been cancelled by
@@ -2357,7 +2360,8 @@
   gpr_mu_lock(&bs->slice_mu);
   if (bs->remaining_bytes < GRPC_SLICE_LENGTH(slice)) {
     incoming_byte_stream_publish_error(
-        exec_ctx, bs, GRPC_ERROR_CREATE("Too many bytes in stream"));
+        exec_ctx, bs,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream"));
   } else {
     bs->remaining_bytes -= (uint32_t)GRPC_SLICE_LENGTH(slice);
     if (bs->on_next != NULL) {
@@ -2377,7 +2381,7 @@
   if (error == GRPC_ERROR_NONE) {
     gpr_mu_lock(&bs->slice_mu);
     if (bs->remaining_bytes != 0) {
-      error = GRPC_ERROR_CREATE("Truncated message");
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
     }
     gpr_mu_unlock(&bs->slice_mu);
   }
@@ -2457,9 +2461,9 @@
               t->peer_string);
     }
     send_goaway(exec_ctx, t,
-                grpc_error_set_int(GRPC_ERROR_CREATE("Buffers full"),
-                                   GRPC_ERROR_INT_HTTP2_ERROR,
-                                   GRPC_HTTP2_ENHANCE_YOUR_CALM));
+                grpc_error_set_int(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"),
+                    GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM));
   } else if (error == GRPC_ERROR_NONE && grpc_resource_quota_trace) {
     gpr_log(GPR_DEBUG,
             "HTTP2: %s - skip benign reclamation, there are still %" PRIdPTR
@@ -2486,9 +2490,10 @@
               s->id);
     }
     grpc_chttp2_cancel_stream(
-        exec_ctx, t, s, grpc_error_set_int(GRPC_ERROR_CREATE("Buffers full"),
-                                           GRPC_ERROR_INT_HTTP2_ERROR,
-                                           GRPC_HTTP2_ENHANCE_YOUR_CALM));
+        exec_ctx, t, s,
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"),
+                           GRPC_ERROR_INT_HTTP2_ERROR,
+                           GRPC_HTTP2_ENHANCE_YOUR_CALM));
     if (n > 1) {
       /* Since we cancel one stream per destructive reclamation, if
          there are more streams left, we can immediately post a new
diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c
index f9b9e1b..6e9258e 100644
--- a/src/core/ext/transport/chttp2/transport/frame_data.c
+++ b/src/core/ext/transport/chttp2/transport/frame_data.c
@@ -54,7 +54,8 @@
                                      grpc_chttp2_data_parser *parser) {
   if (parser->parsing_frame != NULL) {
     grpc_chttp2_incoming_byte_stream_finished(
-        exec_ctx, parser->parsing_frame, GRPC_ERROR_CREATE("Parser destroyed"));
+        exec_ctx, parser->parsing_frame,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Parser destroyed"));
   }
   GRPC_ERROR_UNREF(parser->error);
 }
@@ -65,8 +66,9 @@
   if (flags & ~GRPC_CHTTP2_DATA_FLAG_END_STREAM) {
     char *msg;
     gpr_asprintf(&msg, "unsupported data flags: 0x%02x", flags);
-    grpc_error *err = grpc_error_set_int(
-        GRPC_ERROR_CREATE(msg), GRPC_ERROR_INT_STREAM_ID, (intptr_t)stream_id);
+    grpc_error *err =
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg),
+                           GRPC_ERROR_INT_STREAM_ID, (intptr_t)stream_id);
     gpr_free(msg);
     return err;
   }
@@ -173,13 +175,13 @@
           break;
         default:
           gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type);
-          p->error = GRPC_ERROR_CREATE(msg);
+          p->error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
           p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID,
                                         (intptr_t)s->id);
           gpr_free(msg);
           msg = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
-          p->error =
-              grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, msg);
+          p->error = grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES,
+                                        grpc_slice_from_copied_string(msg));
           gpr_free(msg);
           p->error =
               grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg);
@@ -265,7 +267,8 @@
       }
   }
 
-  GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here"));
+  GPR_UNREACHABLE_CODE(
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here"));
 }
 
 grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.c b/src/core/ext/transport/chttp2/transport/frame_goaway.c
index d99d486..001271d 100644
--- a/src/core/ext/transport/chttp2/transport/frame_goaway.c
+++ b/src/core/ext/transport/chttp2/transport/frame_goaway.c
@@ -54,7 +54,7 @@
   if (length < 8) {
     char *msg;
     gpr_asprintf(&msg, "goaway frame too short (%d bytes)", length);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
@@ -156,7 +156,8 @@
       }
       return GRPC_ERROR_NONE;
   }
-  GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here"));
+  GPR_UNREACHABLE_CODE(
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here"));
 }
 
 void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code,
diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.c b/src/core/ext/transport/chttp2/transport/frame_ping.c
index 9b4b1a7..de8462a 100644
--- a/src/core/ext/transport/chttp2/transport/frame_ping.c
+++ b/src/core/ext/transport/chttp2/transport/frame_ping.c
@@ -71,7 +71,7 @@
   if (flags & 0xfe || length != 8) {
     char *msg;
     gpr_asprintf(&msg, "invalid ping: length=%d, flags=%02x", length, flags);
-    grpc_error *error = GRPC_ERROR_CREATE(msg);
+    grpc_error *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return error;
   }
diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
index cb017e7..225f15c 100644
--- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
+++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
@@ -76,7 +76,7 @@
     char *msg;
     gpr_asprintf(&msg, "invalid rst_stream: length=%d, flags=%02x", length,
                  flags);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
@@ -112,8 +112,9 @@
       char *message;
       gpr_asprintf(&message, "Received RST_STREAM with error code %d", reason);
       error = grpc_error_set_int(
-          grpc_error_set_str(GRPC_ERROR_CREATE("RST_STREAM"),
-                             GRPC_ERROR_STR_GRPC_MESSAGE, message),
+          grpc_error_set_str(GRPC_ERROR_CREATE_FROM_STATIC_STRING("RST_STREAM"),
+                             GRPC_ERROR_STR_GRPC_MESSAGE,
+                             grpc_slice_from_copied_string(message)),
           GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)reason);
       gpr_free(message);
     }
diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.c b/src/core/ext/transport/chttp2/transport/frame_settings.c
index 82290e3..16881c0 100644
--- a/src/core/ext/transport/chttp2/transport/frame_settings.c
+++ b/src/core/ext/transport/chttp2/transport/frame_settings.c
@@ -131,13 +131,16 @@
   if (flags == GRPC_CHTTP2_FLAG_ACK) {
     parser->is_ack = 1;
     if (length != 0) {
-      return GRPC_ERROR_CREATE("non-empty settings ack frame received");
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "non-empty settings ack frame received");
     }
     return GRPC_ERROR_NONE;
   } else if (flags != 0) {
-    return GRPC_ERROR_CREATE("invalid flags on settings frame");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "invalid flags on settings frame");
   } else if (length % 6 != 0) {
-    return GRPC_ERROR_CREATE("settings frames must be a multiple of six bytes");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "settings frames must be a multiple of six bytes");
   } else {
     return GRPC_ERROR_NONE;
   }
@@ -229,7 +232,7 @@
                     &t->qbuf);
                 gpr_asprintf(&msg, "invalid value %u passed for %s",
                              parser->value, sp->name);
-                grpc_error *err = GRPC_ERROR_CREATE(msg);
+                grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
                 gpr_free(msg);
                 return err;
             }
diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.c b/src/core/ext/transport/chttp2/transport/frame_window_update.c
index 8fa0bb4..b76b6f6 100644
--- a/src/core/ext/transport/chttp2/transport/frame_window_update.c
+++ b/src/core/ext/transport/chttp2/transport/frame_window_update.c
@@ -70,7 +70,7 @@
     char *msg;
     gpr_asprintf(&msg, "invalid window update: length=%d, flags=%02x", length,
                  flags);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
@@ -102,7 +102,7 @@
     if (received_update == 0 || (received_update & 0x80000000u)) {
       char *msg;
       gpr_asprintf(&msg, "invalid window update bytes: %d", p->amount);
-      grpc_error *err = GRPC_ERROR_CREATE(msg);
+      grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
       gpr_free(msg);
       return err;
     }
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c
index 1865b99..5099d73 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c
@@ -693,7 +693,7 @@
   }
   if (p->on_header == NULL) {
     GRPC_MDELEM_UNREF(exec_ctx, md);
-    return GRPC_ERROR_CREATE("on_header callback not set");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("on_header callback not set");
   }
   p->on_header(exec_ctx, p->on_header_user_data, md);
   return GRPC_ERROR_NONE;
@@ -810,7 +810,8 @@
   grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
   if (GRPC_MDISNULL(md)) {
     return grpc_error_set_int(
-        grpc_error_set_int(GRPC_ERROR_CREATE("Invalid HPACK index received"),
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                               "Invalid HPACK index received"),
                            GRPC_ERROR_INT_INDEX, (intptr_t)p->index),
         GRPC_ERROR_INT_SIZE, (intptr_t)p->table.num_ents);
   }
@@ -1074,7 +1075,7 @@
   if (p->dynamic_table_update_allowed == 0) {
     return parse_error(
         exec_ctx, p, cur, end,
-        GRPC_ERROR_CREATE(
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING(
             "More than two max table size changes in a single frame"));
   }
   p->dynamic_table_update_allowed--;
@@ -1092,7 +1093,7 @@
   if (p->dynamic_table_update_allowed == 0) {
     return parse_error(
         exec_ctx, p, cur, end,
-        GRPC_ERROR_CREATE(
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING(
             "More than two max table size changes in a single frame"));
   }
   p->dynamic_table_update_allowed--;
@@ -1126,7 +1127,7 @@
   GPR_ASSERT(cur != end);
   char *msg;
   gpr_asprintf(&msg, "Illegal hpack op code %d", *cur);
-  grpc_error *err = GRPC_ERROR_CREATE(msg);
+  grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
   gpr_free(msg);
   return parse_error(exec_ctx, p, cur, end, err);
 }
@@ -1246,7 +1247,7 @@
                "integer overflow in hpack integer decoding: have 0x%08x, "
                "got byte 0x%02x on byte 5",
                *p->parsing.value, *cur);
-  grpc_error *err = GRPC_ERROR_CREATE(msg);
+  grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
   gpr_free(msg);
   return parse_error(exec_ctx, p, cur, end, err);
 }
@@ -1275,7 +1276,7 @@
                "integer overflow in hpack integer decoding: have 0x%08x, "
                "got byte 0x%02x sometime after byte 5",
                *p->parsing.value, *cur);
-  grpc_error *err = GRPC_ERROR_CREATE(msg);
+  grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
   gpr_free(msg);
   return parse_error(exec_ctx, p, cur, end, err);
 }
@@ -1333,8 +1334,9 @@
       bits = inverse_base64[*cur];
       ++cur;
       if (bits == 255)
-        return parse_error(exec_ctx, p, cur, end,
-                           GRPC_ERROR_CREATE("Illegal base64 character"));
+        return parse_error(
+            exec_ctx, p, cur, end,
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
       else if (bits == 64)
         goto b64_byte0;
       p->base64_buffer = bits << 18;
@@ -1348,8 +1350,9 @@
       bits = inverse_base64[*cur];
       ++cur;
       if (bits == 255)
-        return parse_error(exec_ctx, p, cur, end,
-                           GRPC_ERROR_CREATE("Illegal base64 character"));
+        return parse_error(
+            exec_ctx, p, cur, end,
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
       else if (bits == 64)
         goto b64_byte1;
       p->base64_buffer |= bits << 12;
@@ -1363,8 +1366,9 @@
       bits = inverse_base64[*cur];
       ++cur;
       if (bits == 255)
-        return parse_error(exec_ctx, p, cur, end,
-                           GRPC_ERROR_CREATE("Illegal base64 character"));
+        return parse_error(
+            exec_ctx, p, cur, end,
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
       else if (bits == 64)
         goto b64_byte2;
       p->base64_buffer |= bits << 6;
@@ -1378,8 +1382,9 @@
       bits = inverse_base64[*cur];
       ++cur;
       if (bits == 255)
-        return parse_error(exec_ctx, p, cur, end,
-                           GRPC_ERROR_CREATE("Illegal base64 character"));
+        return parse_error(
+            exec_ctx, p, cur, end,
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
       else if (bits == 64)
         goto b64_byte3;
       p->base64_buffer |= bits;
@@ -1391,7 +1396,8 @@
       goto b64_byte0;
   }
   GPR_UNREACHABLE_CODE(return parse_error(
-      exec_ctx, p, cur, end, GRPC_ERROR_CREATE("Should never reach here")));
+      exec_ctx, p, cur, end,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here")));
 }
 
 static grpc_error *finish_str(grpc_exec_ctx *exec_ctx,
@@ -1406,16 +1412,16 @@
     case B64_BYTE0:
       break;
     case B64_BYTE1:
-      return parse_error(
-          exec_ctx, p, cur, end,
-          GRPC_ERROR_CREATE("illegal base64 encoding")); /* illegal encoding */
+      return parse_error(exec_ctx, p, cur, end,
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                             "illegal base64 encoding")); /* illegal encoding */
     case B64_BYTE2:
       bits = p->base64_buffer;
       if (bits & 0xffff) {
         char *msg;
         gpr_asprintf(&msg, "trailing bits in base64 encoding: 0x%04x",
                      bits & 0xffff);
-        grpc_error *err = GRPC_ERROR_CREATE(msg);
+        grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
         gpr_free(msg);
         return parse_error(exec_ctx, p, cur, end, err);
       }
@@ -1428,7 +1434,7 @@
         char *msg;
         gpr_asprintf(&msg, "trailing bits in base64 encoding: 0x%02x",
                      bits & 0xff);
-        grpc_error *err = GRPC_ERROR_CREATE(msg);
+        grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
         gpr_free(msg);
         return parse_error(exec_ctx, p, cur, end, err);
       }
@@ -1550,7 +1556,8 @@
   grpc_mdelem elem = grpc_chttp2_hptbl_lookup(&p->table, p->index);
   if (GRPC_MDISNULL(elem)) {
     return grpc_error_set_int(
-        grpc_error_set_int(GRPC_ERROR_CREATE("Invalid HPACK index received"),
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                               "Invalid HPACK index received"),
                            GRPC_ERROR_INT_INDEX, (intptr_t)p->index),
         GRPC_ERROR_INT_SIZE, (intptr_t)p->table.num_ents);
   }
@@ -1675,7 +1682,7 @@
   if (is_last) {
     if (parser->is_boundary && parser->state != parse_begin) {
       GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0);
-      return GRPC_ERROR_CREATE(
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
           "end of header frame not aligned with a hpack record boundary");
     }
     /* need to check for null stream: this can occur if we receive an invalid
@@ -1683,7 +1690,8 @@
     if (s != NULL) {
       if (parser->is_boundary) {
         if (s->header_frames_received == GPR_ARRAY_SIZE(s->metadata_buffer)) {
-          return GRPC_ERROR_CREATE("Too many trailer frames");
+          return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+              "Too many trailer frames");
         }
         s->published_metadata[s->header_frames_received] =
             GRPC_METADATA_PUBLISHED_FROM_WIRE;
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.c b/src/core/ext/transport/chttp2/transport/hpack_table.c
index 62dd1b8..9dd41fd 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.c
@@ -280,7 +280,7 @@
     gpr_asprintf(&msg,
                  "Attempt to make hpack table %d bytes when max is %d bytes",
                  bytes, tbl->max_bytes);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
@@ -317,7 +317,7 @@
         "HPACK max table size reduced to %d but not reflected by hpack "
         "stream (still at %d)",
         tbl->max_bytes, tbl->current_table_bytes);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c
index 7efc8c6..7e457ce 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.c
+++ b/src/core/ext/transport/chttp2/transport/parsing.c
@@ -116,7 +116,7 @@
               GRPC_CHTTP2_CLIENT_CONNECT_STRING[t->deframe_state],
               (int)(uint8_t)GRPC_CHTTP2_CLIENT_CONNECT_STRING[t->deframe_state],
               *cur, (int)*cur, t->deframe_state);
-          err = GRPC_ERROR_CREATE(msg);
+          err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
           gpr_free(msg);
           return err;
         }
@@ -219,7 +219,7 @@
                      t->incoming_frame_size,
                      t->settings[GRPC_ACKED_SETTINGS]
                                 [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]);
-        err = GRPC_ERROR_CREATE(msg);
+        err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
         gpr_free(msg);
         return err;
       }
@@ -278,7 +278,7 @@
     gpr_asprintf(
         &msg, "Expected SETTINGS frame as the first frame, got frame type %d",
         t->incoming_frame_type);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
@@ -288,7 +288,7 @@
       char *msg;
       gpr_asprintf(&msg, "Expected CONTINUATION frame, got frame type %02x",
                    t->incoming_frame_type);
-      grpc_error *err = GRPC_ERROR_CREATE(msg);
+      grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
       gpr_free(msg);
       return err;
     }
@@ -299,7 +299,7 @@
           "Expected CONTINUATION frame for grpc_chttp2_stream %08x, got "
           "grpc_chttp2_stream %08x",
           t->expect_continuation_stream_id, t->incoming_stream_id);
-      grpc_error *err = GRPC_ERROR_CREATE(msg);
+      grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
       gpr_free(msg);
       return err;
     }
@@ -311,7 +311,8 @@
     case GRPC_CHTTP2_FRAME_HEADER:
       return init_header_frame_parser(exec_ctx, t, 0);
     case GRPC_CHTTP2_FRAME_CONTINUATION:
-      return GRPC_ERROR_CREATE("Unexpected CONTINUATION frame");
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "Unexpected CONTINUATION frame");
     case GRPC_CHTTP2_FRAME_RST_STREAM:
       return init_rst_stream_parser(exec_ctx, t);
     case GRPC_CHTTP2_FRAME_SETTINGS:
@@ -371,7 +372,7 @@
     char *msg;
     gpr_asprintf(&msg, "frame of size %d overflows incoming window of %" PRId64,
                  t->incoming_frame_size, t->incoming_window);
-    grpc_error *err = GRPC_ERROR_CREATE(msg);
+    grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return err;
   }
@@ -409,7 +410,7 @@
                      s->incoming_window_delta +
                          t->settings[GRPC_ACKED_SETTINGS]
                                     [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
-        grpc_error *err = GRPC_ERROR_CREATE(msg);
+        grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
         gpr_free(msg);
         return err;
       }
@@ -542,7 +543,8 @@
       grpc_chttp2_cancel_stream(
           exec_ctx, t, s,
           grpc_error_set_int(
-              GRPC_ERROR_CREATE("received initial metadata size exceeds limit"),
+              GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                  "received initial metadata size exceeds limit"),
               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
       grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
       s->seen_error = true;
@@ -598,9 +600,10 @@
             new_size, metadata_size_limit);
     grpc_chttp2_cancel_stream(
         exec_ctx, t, s,
-        grpc_error_set_int(
-            GRPC_ERROR_CREATE("received trailing metadata size exceeds limit"),
-            GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                               "received trailing metadata size exceeds limit"),
+                           GRPC_ERROR_INT_GRPC_STATUS,
+                           GRPC_STATUS_RESOURCE_EXHAUSTED));
     grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
     s->seen_error = true;
     GRPC_MDELEM_UNREF(exec_ctx, md);
@@ -771,7 +774,8 @@
 static grpc_error *init_settings_frame_parser(grpc_exec_ctx *exec_ctx,
                                               grpc_chttp2_transport *t) {
   if (t->incoming_stream_id != 0) {
-    return GRPC_ERROR_CREATE("Settings frame received for grpc_chttp2_stream");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Settings frame received for grpc_chttp2_stream");
   }
 
   grpc_error *err = grpc_chttp2_settings_parser_begin_frame(
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index 36bb678..952690e 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -290,7 +290,7 @@
 }
 
 static grpc_error *make_error_with_desc(int error_code, const char *desc) {
-  grpc_error *error = GRPC_ERROR_CREATE(desc);
+  grpc_error *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(desc);
   error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, error_code);
   return error;
 }
diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c
index 42ef7b7..75c68a5 100644
--- a/src/core/lib/channel/connected_channel.c
+++ b/src/core/lib/channel/connected_channel.c
@@ -90,7 +90,8 @@
       exec_ctx, chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld),
       &args->call_stack->refcount, args->server_transport_data, args->arena);
   return r == 0 ? GRPC_ERROR_NONE
-                : GRPC_ERROR_CREATE("transport stream initialization failed");
+                : GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                      "transport stream initialization failed");
 }
 
 static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/channel/deadline_filter.c b/src/core/lib/channel/deadline_filter.c
index 34114bb..ca701ed 100644
--- a/src/core/lib/channel/deadline_filter.c
+++ b/src/core/lib/channel/deadline_filter.c
@@ -55,9 +55,9 @@
   if (error != GRPC_ERROR_CANCELLED) {
     grpc_call_element_signal_error(
         exec_ctx, elem,
-        grpc_error_set_int(GRPC_ERROR_CREATE("Deadline Exceeded"),
-                           GRPC_ERROR_INT_GRPC_STATUS,
-                           GRPC_STATUS_DEADLINE_EXCEEDED));
+        grpc_error_set_int(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Deadline Exceeded"),
+            GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_DEADLINE_EXCEEDED));
   }
   GRPC_CALL_STACK_UNREF(exec_ctx, deadline_state->call_stack, "deadline_timer");
 }
diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c
index 1b4240b..5861fa6 100644
--- a/src/core/lib/channel/handshaker.c
+++ b/src/core/lib/channel/handshaker.c
@@ -236,8 +236,9 @@
 static void on_timeout(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
   grpc_handshake_manager* mgr = arg;
   if (error == GRPC_ERROR_NONE) {  // Timer fired, rather than being cancelled.
-    grpc_handshake_manager_shutdown(exec_ctx, mgr,
-                                    GRPC_ERROR_CREATE("Handshake timed out"));
+    grpc_handshake_manager_shutdown(
+        exec_ctx, mgr,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake timed out"));
   }
   grpc_handshake_manager_unref(exec_ctx, mgr);
 }
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index f9d0d68..028e9a5 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -108,11 +108,11 @@
       grpc_error *e = grpc_error_set_str(
           grpc_error_set_int(
               grpc_error_set_str(
-                  GRPC_ERROR_CREATE(
+                  GRPC_ERROR_CREATE_FROM_STATIC_STRING(
                       "Received http2 :status header with non-200 OK status"),
-                  GRPC_ERROR_STR_VALUE, val),
+                  GRPC_ERROR_STR_VALUE, grpc_slice_from_copied_string(val)),
               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED),
-          GRPC_ERROR_STR_GRPC_MESSAGE, msg);
+          GRPC_ERROR_STR_GRPC_MESSAGE, grpc_slice_from_copied_string(msg));
       gpr_free(val);
       gpr_free(msg);
       return e;
diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c
index bebd3af..41a325b 100644
--- a/src/core/lib/channel/http_server_filter.c
+++ b/src/core/lib/channel/http_server_filter.c
@@ -101,7 +101,7 @@
                       grpc_error *new) {
   if (new == GRPC_ERROR_NONE) return;
   if (*cumulative == GRPC_ERROR_NONE) {
-    *cumulative = GRPC_ERROR_CREATE(error_name);
+    *cumulative = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_name);
   }
   *cumulative = grpc_error_add_child(*cumulative, new);
 }
@@ -125,27 +125,32 @@
       *calld->recv_cacheable_request = true;
     } else {
       add_error(error_name, &error,
-                grpc_attach_md_to_error(GRPC_ERROR_CREATE("Bad header"),
-                                        b->idx.named.method->md));
+                grpc_attach_md_to_error(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"),
+                    b->idx.named.method->md));
     }
     grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.method);
   } else {
-    add_error(error_name, &error,
-              grpc_error_set_str(GRPC_ERROR_CREATE("Missing header"),
-                                 GRPC_ERROR_STR_KEY, ":method"));
+    add_error(
+        error_name, &error,
+        grpc_error_set_str(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing header"),
+            GRPC_ERROR_STR_KEY, grpc_slice_from_static_string(":method")));
   }
 
   if (b->idx.named.te != NULL) {
     if (!grpc_mdelem_eq(b->idx.named.te->md, GRPC_MDELEM_TE_TRAILERS)) {
       add_error(error_name, &error,
-                grpc_attach_md_to_error(GRPC_ERROR_CREATE("Bad header"),
-                                        b->idx.named.te->md));
+                grpc_attach_md_to_error(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"),
+                    b->idx.named.te->md));
     }
     grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.te);
   } else {
     add_error(error_name, &error,
-              grpc_error_set_str(GRPC_ERROR_CREATE("Missing header"),
-                                 GRPC_ERROR_STR_KEY, "te"));
+              grpc_error_set_str(
+                  GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing header"),
+                  GRPC_ERROR_STR_KEY, grpc_slice_from_static_string("te")));
   }
 
   if (b->idx.named.scheme != NULL) {
@@ -153,14 +158,17 @@
         !grpc_mdelem_eq(b->idx.named.scheme->md, GRPC_MDELEM_SCHEME_HTTPS) &&
         !grpc_mdelem_eq(b->idx.named.scheme->md, GRPC_MDELEM_SCHEME_GRPC)) {
       add_error(error_name, &error,
-                grpc_attach_md_to_error(GRPC_ERROR_CREATE("Bad header"),
-                                        b->idx.named.scheme->md));
+                grpc_attach_md_to_error(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"),
+                    b->idx.named.scheme->md));
     }
     grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.scheme);
   } else {
-    add_error(error_name, &error,
-              grpc_error_set_str(GRPC_ERROR_CREATE("Missing header"),
-                                 GRPC_ERROR_STR_KEY, ":scheme"));
+    add_error(
+        error_name, &error,
+        grpc_error_set_str(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing header"),
+            GRPC_ERROR_STR_KEY, grpc_slice_from_static_string(":scheme")));
   }
 
   if (b->idx.named.content_type != NULL) {
@@ -194,8 +202,9 @@
 
   if (b->idx.named.path == NULL) {
     add_error(error_name, &error,
-              grpc_error_set_str(GRPC_ERROR_CREATE("Missing header"),
-                                 GRPC_ERROR_STR_KEY, ":path"));
+              grpc_error_set_str(
+                  GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing header"),
+                  GRPC_ERROR_STR_KEY, grpc_slice_from_static_string(":path")));
   }
 
   if (b->idx.named.host != NULL && b->idx.named.authority == NULL) {
@@ -212,9 +221,11 @@
   }
 
   if (b->idx.named.authority == NULL) {
-    add_error(error_name, &error,
-              grpc_error_set_str(GRPC_ERROR_CREATE("Missing header"),
-                                 GRPC_ERROR_STR_KEY, ":authority"));
+    add_error(
+        error_name, &error,
+        grpc_error_set_str(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing header"),
+            GRPC_ERROR_STR_KEY, grpc_slice_from_static_string(":authority")));
   }
 
   if (b->idx.named.grpc_payload_bin != NULL) {
diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c
index 5ba13fe..6313665 100644
--- a/src/core/lib/channel/message_size_filter.c
+++ b/src/core/lib/channel/message_size_filter.c
@@ -121,8 +121,8 @@
                  "Received message larger than max (%u vs. %d)",
                  (*calld->recv_message)->length, calld->max_recv_size);
     grpc_error* new_error = grpc_error_set_int(
-        GRPC_ERROR_CREATE(message_string), GRPC_ERROR_INT_GRPC_STATUS,
-        GRPC_STATUS_INVALID_ARGUMENT);
+        GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string),
+        GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INVALID_ARGUMENT);
     if (error == GRPC_ERROR_NONE) {
       error = new_error;
     } else {
@@ -147,9 +147,10 @@
     gpr_asprintf(&message_string, "Sent message larger than max (%u vs. %d)",
                  op->send_message->length, calld->max_send_size);
     grpc_transport_stream_op_finish_with_failure(
-        exec_ctx, op, grpc_error_set_int(GRPC_ERROR_CREATE(message_string),
-                                         GRPC_ERROR_INT_GRPC_STATUS,
-                                         GRPC_STATUS_INVALID_ARGUMENT));
+        exec_ctx, op,
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string),
+                           GRPC_ERROR_INT_GRPC_STATUS,
+                           GRPC_STATUS_INVALID_ARGUMENT));
     gpr_free(message_string);
     return;
   }
diff --git a/src/core/lib/http/httpcli.c b/src/core/lib/http/httpcli.c
index 6d7aa43..453a64b 100644
--- a/src/core/lib/http/httpcli.c
+++ b/src/core/lib/http/httpcli.c
@@ -126,13 +126,15 @@
 
 static void append_error(internal_request *req, grpc_error *error) {
   if (req->overall_error == GRPC_ERROR_NONE) {
-    req->overall_error = GRPC_ERROR_CREATE("Failed HTTP/1 client request");
+    req->overall_error =
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed HTTP/1 client request");
   }
   grpc_resolved_address *addr = &req->addresses->addrs[req->next_address - 1];
   char *addr_text = grpc_sockaddr_to_uri(addr);
   req->overall_error = grpc_error_add_child(
       req->overall_error,
-      grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, addr_text));
+      grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS,
+                         grpc_slice_from_copied_string(addr_text)));
   gpr_free(addr_text);
 }
 
@@ -190,8 +192,8 @@
   internal_request *req = arg;
 
   if (!ep) {
-    next_address(exec_ctx, req,
-                 GRPC_ERROR_CREATE("Unexplained handshake failure"));
+    next_address(exec_ctx, req, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                    "Unexplained handshake failure"));
     return;
   }
 
@@ -221,8 +223,8 @@
   }
   if (req->next_address == req->addresses->naddrs) {
     finish(exec_ctx, req,
-           GRPC_ERROR_CREATE_REFERENCING("Failed HTTP requests to all targets",
-                                         &req->overall_error, 1));
+           GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+               "Failed HTTP requests to all targets", &req->overall_error, 1));
     return;
   }
   addr = &req->addresses->addrs[req->next_address++];
diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c
index 354d2f4..be6a6d6 100644
--- a/src/core/lib/http/httpcli_security_connector.c
+++ b/src/core/lib/http/httpcli_security_connector.c
@@ -95,7 +95,7 @@
     char *msg;
     gpr_asprintf(&msg, "Peer name %s is not in peer certificate",
                  c->secure_peer_name);
-    error = GRPC_ERROR_CREATE(msg);
+    error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
   }
   grpc_closure_sched(exec_ctx, on_peer_checked, error);
diff --git a/src/core/lib/http/parser.c b/src/core/lib/http/parser.c
index b9c56c1..aac506b 100644
--- a/src/core/lib/http/parser.c
+++ b/src/core/lib/http/parser.c
@@ -54,26 +54,36 @@
   uint8_t *cur = beg;
   uint8_t *end = beg + parser->cur_line_length;
 
-  if (cur == end || *cur++ != 'H') return GRPC_ERROR_CREATE("Expected 'H'");
-  if (cur == end || *cur++ != 'T') return GRPC_ERROR_CREATE("Expected 'T'");
-  if (cur == end || *cur++ != 'T') return GRPC_ERROR_CREATE("Expected 'T'");
-  if (cur == end || *cur++ != 'P') return GRPC_ERROR_CREATE("Expected 'P'");
-  if (cur == end || *cur++ != '/') return GRPC_ERROR_CREATE("Expected '/'");
-  if (cur == end || *cur++ != '1') return GRPC_ERROR_CREATE("Expected '1'");
-  if (cur == end || *cur++ != '.') return GRPC_ERROR_CREATE("Expected '.'");
+  if (cur == end || *cur++ != 'H')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'H'");
+  if (cur == end || *cur++ != 'T')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
+  if (cur == end || *cur++ != 'T')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
+  if (cur == end || *cur++ != 'P')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'P'");
+  if (cur == end || *cur++ != '/')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '/'");
+  if (cur == end || *cur++ != '1')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '1'");
+  if (cur == end || *cur++ != '.')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '.'");
   if (cur == end || *cur < '0' || *cur++ > '1') {
-    return GRPC_ERROR_CREATE("Expected HTTP/1.0 or HTTP/1.1");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Expected HTTP/1.0 or HTTP/1.1");
   }
-  if (cur == end || *cur++ != ' ') return GRPC_ERROR_CREATE("Expected ' '");
+  if (cur == end || *cur++ != ' ')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected ' '");
   if (cur == end || *cur < '1' || *cur++ > '9')
-    return GRPC_ERROR_CREATE("Expected status code");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected status code");
   if (cur == end || *cur < '0' || *cur++ > '9')
-    return GRPC_ERROR_CREATE("Expected status code");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected status code");
   if (cur == end || *cur < '0' || *cur++ > '9')
-    return GRPC_ERROR_CREATE("Expected status code");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected status code");
   parser->http.response->status =
       (cur[-3] - '0') * 100 + (cur[-2] - '0') * 10 + (cur[-1] - '0');
-  if (cur == end || *cur++ != ' ') return GRPC_ERROR_CREATE("Expected ' '");
+  if (cur == end || *cur++ != ' ')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected ' '");
 
   /* we don't really care about the status code message */
 
@@ -89,24 +99,33 @@
 
   while (cur != end && *cur++ != ' ')
     ;
-  if (cur == end) return GRPC_ERROR_CREATE("No method on HTTP request line");
+  if (cur == end)
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "No method on HTTP request line");
   parser->http.request->method = buf2str(beg, (size_t)(cur - beg - 1));
 
   beg = cur;
   while (cur != end && *cur++ != ' ')
     ;
-  if (cur == end) return GRPC_ERROR_CREATE("No path on HTTP request line");
+  if (cur == end)
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("No path on HTTP request line");
   parser->http.request->path = buf2str(beg, (size_t)(cur - beg - 1));
 
-  if (cur == end || *cur++ != 'H') return GRPC_ERROR_CREATE("Expected 'H'");
-  if (cur == end || *cur++ != 'T') return GRPC_ERROR_CREATE("Expected 'T'");
-  if (cur == end || *cur++ != 'T') return GRPC_ERROR_CREATE("Expected 'T'");
-  if (cur == end || *cur++ != 'P') return GRPC_ERROR_CREATE("Expected 'P'");
-  if (cur == end || *cur++ != '/') return GRPC_ERROR_CREATE("Expected '/'");
+  if (cur == end || *cur++ != 'H')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'H'");
+  if (cur == end || *cur++ != 'T')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
+  if (cur == end || *cur++ != 'T')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
+  if (cur == end || *cur++ != 'P')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'P'");
+  if (cur == end || *cur++ != '/')
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '/'");
   vers_major = (uint8_t)(*cur++ - '1' + 1);
   ++cur;
   if (cur == end)
-    return GRPC_ERROR_CREATE("End of line in HTTP version string");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "End of line in HTTP version string");
   vers_minor = (uint8_t)(*cur++ - '1' + 1);
 
   if (vers_major == 1) {
@@ -115,18 +134,19 @@
     } else if (vers_minor == 1) {
       parser->http.request->version = GRPC_HTTP_HTTP11;
     } else {
-      return GRPC_ERROR_CREATE(
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
           "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
     }
   } else if (vers_major == 2) {
     if (vers_minor == 0) {
       parser->http.request->version = GRPC_HTTP_HTTP20;
     } else {
-      return GRPC_ERROR_CREATE(
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
           "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
     }
   } else {
-    return GRPC_ERROR_CREATE("Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
   }
 
   return GRPC_ERROR_NONE;
@@ -139,7 +159,8 @@
     case GRPC_HTTP_RESPONSE:
       return handle_response_line(parser);
   }
-  GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here"));
+  GPR_UNREACHABLE_CODE(
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here"));
 }
 
 static grpc_error *add_header(grpc_http_parser *parser) {
@@ -154,7 +175,8 @@
   GPR_ASSERT(cur != end);
 
   if (*cur == ' ' || *cur == '\t') {
-    error = GRPC_ERROR_CREATE("Continued header lines not supported yet");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Continued header lines not supported yet");
     goto done;
   }
 
@@ -162,7 +184,8 @@
     cur++;
   }
   if (cur == end) {
-    error = GRPC_ERROR_CREATE("Didn't find ':' in header string");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Didn't find ':' in header string");
     goto done;
   }
   GPR_ASSERT(cur >= beg);
@@ -222,7 +245,8 @@
       }
       break;
     case GRPC_HTTP_BODY:
-      GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here"));
+      GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "Should never reach here"));
   }
 
   parser->cur_line_length = 0;
@@ -240,7 +264,8 @@
     body_length = &parser->http.request->body_length;
     body = &parser->http.request->body;
   } else {
-    GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here"));
+    GPR_UNREACHABLE_CODE(
+        return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here"));
   }
 
   if (*body_length == parser->body_capacity) {
@@ -286,7 +311,8 @@
         if (grpc_http1_trace)
           gpr_log(GPR_ERROR, "HTTP header max line length (%d) exceeded",
                   GRPC_HTTP_PARSER_MAX_HEADER_LENGTH);
-        return GRPC_ERROR_CREATE("HTTP header max line length exceeded");
+        return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+            "HTTP header max line length exceeded");
       }
       parser->cur_line[parser->cur_line_length] = byte;
       parser->cur_line_length++;
@@ -347,7 +373,7 @@
 
 grpc_error *grpc_http_parser_eof(grpc_http_parser *parser) {
   if (parser->state != GRPC_HTTP_BODY) {
-    return GRPC_ERROR_CREATE("Did not finish headers");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Did not finish headers");
   }
   return GRPC_ERROR_NONE;
 }
diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c
index 1127fff..1dbb64e 100644
--- a/src/core/lib/iomgr/error.c
+++ b/src/core/lib/iomgr/error.c
@@ -35,7 +35,6 @@
 
 #include <string.h>
 
-#include <grpc/slice.h>
 #include <grpc/status.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
@@ -287,7 +286,7 @@
 // It is very common to include and extra int and string in an error
 #define SURPLUS_CAPACITY (2 * SLOTS_PER_INT + SLOTS_PER_TIME)
 
-grpc_error *grpc_error_create(const char *file, int line, const char *desc,
+grpc_error *grpc_error_create(grpc_slice file, int line, grpc_slice desc,
                               grpc_error **referencing,
                               size_t num_referencing) {
   GPR_TIMER_BEGIN("grpc_error_create", 0);
@@ -313,14 +312,8 @@
   memset(err->times, UINT8_MAX, GRPC_ERROR_TIME_MAX);
 
   internal_set_int(&err, GRPC_ERROR_INT_FILE_LINE, line);
-  internal_set_str(&err, GRPC_ERROR_STR_FILE,
-                   grpc_slice_from_static_string(file));
-  internal_set_str(
-      &err, GRPC_ERROR_STR_DESCRIPTION,
-      grpc_slice_from_copied_buffer(
-          desc,
-          strlen(desc) +
-              1));  // TODO, pull this up.  // TODO(ncteisen), pull this up.
+  internal_set_str(&err, GRPC_ERROR_STR_FILE, file);
+  internal_set_str(&err, GRPC_ERROR_STR_DESCRIPTION, desc);
 
   for (size_t i = 0; i < num_referencing; ++i) {
     if (referencing[i] == GRPC_ERROR_NONE) continue;
@@ -360,7 +353,7 @@
   GPR_TIMER_BEGIN("copy_error_and_unref", 0);
   grpc_error *out;
   if (grpc_error_is_special(in)) {
-    out = GRPC_ERROR_CREATE("unknown");
+    out = GRPC_ERROR_CREATE_FROM_STATIC_STRING("unknown");
     if (in == GRPC_ERROR_NONE) {
       internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION,
                        grpc_slice_from_static_string("no error"));
@@ -417,7 +410,7 @@
   const char *msg;
 } special_error_status_map;
 static special_error_status_map error_status_map[] = {
-    {GRPC_ERROR_NONE, GRPC_STATUS_OK, NULL},
+    {GRPC_ERROR_NONE, GRPC_STATUS_OK, ""},
     {GRPC_ERROR_CANCELLED, GRPC_STATUS_CANCELLED, "Cancelled"},
     {GRPC_ERROR_OOM, GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"},
 };
@@ -448,33 +441,33 @@
 }
 
 grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
-                               const char *value) {
+                               grpc_slice str) {
   GPR_TIMER_BEGIN("grpc_error_set_str", 0);
   grpc_error *new = copy_error_and_unref(src);
-  internal_set_str(&new, which,
-                   grpc_slice_from_copied_buffer(
-                       value, strlen(value) + 1));  // TODO, pull this up.
+  internal_set_str(&new, which, str);
   GPR_TIMER_END("grpc_error_set_str", 0);
   return new;
 }
 
-const char *grpc_error_get_str(grpc_error *err, grpc_error_strs which) {
+bool grpc_error_get_str(grpc_error *err, grpc_error_strs which,
+                        grpc_slice *str) {
   if (grpc_error_is_special(err)) {
     if (which == GRPC_ERROR_STR_GRPC_MESSAGE) {
       for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) {
         if (error_status_map[i].error == err) {
-          return error_status_map[i].msg;
+          *str = grpc_slice_from_static_string(error_status_map[i].msg);
+          return true;
         }
       }
     }
-    return NULL;
+    return false;
   }
   uint8_t slot = err->strs[which];
   if (slot != UINT8_MAX) {
-    return (const char *)GRPC_SLICE_START_PTR(
-        *(grpc_slice *)(err->arena + slot));
+    *str = *(grpc_slice *)(err->arena + slot);
+    return true;
   } else {
-    return NULL;
+    return false;
   }
 }
 
@@ -515,13 +508,14 @@
   }
 }
 
-static void append_esc_str(const char *str, char **s, size_t *sz, size_t *cap) {
+static void append_esc_str(const uint8_t *str, size_t len, char **s, size_t *sz,
+                           size_t *cap) {
   static const char *hex = "0123456789abcdef";
   append_chr('"', s, sz, cap);
-  for (const uint8_t *c = (const uint8_t *)str; *c; c++) {
-    if (*c < 32 || *c >= 127) {
+  for (size_t i = 0; i < len; i++, str++) {
+    if (*str < 32 || *str >= 127) {
       append_chr('\\', s, sz, cap);
-      switch (*c) {
+      switch (*str) {
         case '\b':
           append_chr('b', s, sz, cap);
           break;
@@ -541,12 +535,12 @@
           append_chr('u', s, sz, cap);
           append_chr('0', s, sz, cap);
           append_chr('0', s, sz, cap);
-          append_chr(hex[*c >> 4], s, sz, cap);
-          append_chr(hex[*c & 0x0f], s, sz, cap);
+          append_chr(hex[*str >> 4], s, sz, cap);
+          append_chr(hex[*str & 0x0f], s, sz, cap);
           break;
       }
     } else {
-      append_chr((char)*c, s, sz, cap);
+      append_chr((char)*str, s, sz, cap);
     }
   }
   append_chr('"', s, sz, cap);
@@ -586,11 +580,12 @@
   return gpr_strdup(error_str_name(which));
 }
 
-static char *fmt_str(void *p) {
+static char *fmt_str(grpc_slice slice) {
   char *s = NULL;
   size_t sz = 0;
   size_t cap = 0;
-  append_esc_str(p, &s, &sz, &cap);
+  append_esc_str((const uint8_t *)GRPC_SLICE_START_PTR(slice),
+                 GRPC_SLICE_LENGTH(slice), &s, &sz, &cap);
   append_chr(0, &s, &sz, &cap);
   return s;
 }
@@ -599,9 +594,8 @@
   for (size_t which = 0; which < GRPC_ERROR_STR_MAX; ++which) {
     uint8_t slot = err->strs[which];
     if (slot != UINT8_MAX) {
-      append_kv(
-          kvs, key_str((grpc_error_strs)which),
-          fmt_str(GRPC_SLICE_START_PTR(*(grpc_slice *)(err->arena + slot))));
+      append_kv(kvs, key_str((grpc_error_strs)which),
+                fmt_str(*(grpc_slice *)(err->arena + slot)));
     }
   }
 }
@@ -681,7 +675,8 @@
   append_chr('{', &s, &sz, &cap);
   for (size_t i = 0; i < kvs->num_kvs; i++) {
     if (i != 0) append_chr(',', &s, &sz, &cap);
-    append_esc_str(kvs->kvs[i].key, &s, &sz, &cap);
+    append_esc_str((const uint8_t *)kvs->kvs[i].key, strlen(kvs->kvs[i].key),
+                   &s, &sz, &cap);
     gpr_free(kvs->kvs[i].key);
     append_chr(':', &s, &sz, &cap);
     append_str(kvs->kvs[i].value, &s, &sz, &cap);
@@ -733,10 +728,14 @@
                           const char *call_name) {
   return grpc_error_set_str(
       grpc_error_set_str(
-          grpc_error_set_int(grpc_error_create(file, line, "OS Error", NULL, 0),
-                             GRPC_ERROR_INT_ERRNO, err),
-          GRPC_ERROR_STR_OS_ERROR, strerror(err)),
-      GRPC_ERROR_STR_SYSCALL, call_name);
+          grpc_error_set_int(
+              grpc_error_create(grpc_slice_from_static_string(file), line,
+                                grpc_slice_from_static_string("OS Error"), NULL,
+                                0),
+              GRPC_ERROR_INT_ERRNO, err),
+          GRPC_ERROR_STR_OS_ERROR,
+          grpc_slice_from_static_string(strerror(err))),
+      GRPC_ERROR_STR_SYSCALL, grpc_slice_from_static_string(call_name));
 }
 
 #ifdef GPR_WINDOWS
@@ -745,10 +744,13 @@
   char *utf8_message = gpr_format_message(err);
   grpc_error *error = grpc_error_set_str(
       grpc_error_set_str(
-          grpc_error_set_int(grpc_error_create(file, line, "OS Error", NULL, 0),
-                             GRPC_ERROR_INT_WSA_ERROR, err),
-          GRPC_ERROR_STR_OS_ERROR, utf8_message),
-      GRPC_ERROR_STR_SYSCALL, call_name);
+          grpc_error_set_int(
+              grpc_error_create(grpc_slice_from_static_string(file), line,
+                                grpc_slice_from_static_string("OS Error"), NULL,
+                                0),
+              GRPC_ERROR_INT_WSA_ERROR, err),
+          GRPC_ERROR_STR_OS_ERROR, grpc_slice_from_copied_string(utf8_message)),
+      GRPC_ERROR_STR_SYSCALL, grpc_slice_from_static_string(call_name));
   gpr_free(utf8_message);
   return error;
 }
diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h
index 0e7a7b0..2a44fcf 100644
--- a/src/core/lib/iomgr/error.h
+++ b/src/core/lib/iomgr/error.h
@@ -37,6 +37,7 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include <grpc/slice.h>
 #include <grpc/status.h>
 #include <grpc/support/time.h>
 
@@ -137,7 +138,7 @@
 const char *grpc_error_string(grpc_error *error);
 
 /// Create an error - but use GRPC_ERROR_CREATE instead
-grpc_error *grpc_error_create(const char *file, int line, const char *desc,
+grpc_error *grpc_error_create(grpc_slice file, int line, grpc_slice desc,
                               grpc_error **referencing, size_t num_referencing);
 /// Create an error (this is the preferred way of generating an error that is
 ///   not due to a system call - for system calls, use GRPC_OS_ERROR or
@@ -147,13 +148,21 @@
 /// err = grpc_error_create(x, y, z, r, nr) is equivalent to:
 ///   err = grpc_error_create(x, y, z, NULL, 0);
 ///   for (i=0; i<nr; i++) err = grpc_error_add_child(err, r[i]);
-#define GRPC_ERROR_CREATE(desc) \
-  grpc_error_create(__FILE__, __LINE__, desc, NULL, 0)
+#define GRPC_ERROR_CREATE_FROM_STATIC_STRING(desc)                     \
+  grpc_error_create(grpc_slice_from_static_string(__FILE__), __LINE__, \
+                    grpc_slice_from_static_string(desc), NULL, 0)
+#define GRPC_ERROR_CREATE_FROM_COPIED_STRING(desc)                     \
+  grpc_error_create(grpc_slice_from_static_string(__FILE__), __LINE__, \
+                    grpc_slice_from_copied_string(desc), NULL, 0)
 
 // Create an error that references some other errors. This function adds a
 // reference to each error in errs - it does not consume an existing reference
-#define GRPC_ERROR_CREATE_REFERENCING(desc, errs, count) \
-  grpc_error_create(__FILE__, __LINE__, desc, errs, count)
+#define GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(desc, errs, count) \
+  grpc_error_create(grpc_slice_from_static_string(__FILE__), __LINE__,      \
+                    grpc_slice_from_static_string(desc), errs, count)
+#define GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(desc, errs, count) \
+  grpc_error_create(grpc_slice_from_static_string(__FILE__), __LINE__,      \
+                    grpc_slice_from_copied_string(desc), errs, count)
 
 //#define GRPC_ERROR_REFCOUNT_DEBUG
 #ifdef GRPC_ERROR_REFCOUNT_DEBUG
@@ -175,10 +184,11 @@
                                intptr_t value) GRPC_MUST_USE_RESULT;
 bool grpc_error_get_int(grpc_error *error, grpc_error_ints which, intptr_t *p);
 grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
-                               const char *value) GRPC_MUST_USE_RESULT;
-/// Returns NULL if the specified string is not set.
-/// Caller does NOT own return value.
-const char *grpc_error_get_str(grpc_error *error, grpc_error_strs which);
+                               grpc_slice str) GRPC_MUST_USE_RESULT;
+/// Returns false if the specified string is not set.
+/// Caller does NOT own the slice.
+bool grpc_error_get_str(grpc_error *error, grpc_error_strs which,
+                        grpc_slice *s);
 
 /// Add a child error: an error that is believed to have contributed to this
 /// error occurring. Allows root causing high level errors from lower level
diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index 11208b9..1924e76 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -321,7 +321,7 @@
                          const char *desc) {
   if (error == GRPC_ERROR_NONE) return true;
   if (*composite == GRPC_ERROR_NONE) {
-    *composite = GRPC_ERROR_CREATE(desc);
+    *composite = GRPC_ERROR_CREATE_FROM_COPIED_STRING(desc);
   }
   *composite = grpc_error_add_child(*composite, error);
   return false;
@@ -1146,9 +1146,9 @@
            schedule the closure with the shutdown error */
         if ((curr & FD_SHUTDOWN_BIT) > 0) {
           grpc_error *shutdown_err = (grpc_error *)(curr & ~FD_SHUTDOWN_BIT);
-          grpc_closure_sched(
-              exec_ctx, closure,
-              GRPC_ERROR_CREATE_REFERENCING("FD Shutdown", &shutdown_err, 1));
+          grpc_closure_sched(exec_ctx, closure,
+                             GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                                 "FD Shutdown", &shutdown_err, 1));
           return;
         }
 
@@ -1203,9 +1203,9 @@
            notify_on to ensure that the closure it schedules 'happens-after'
            the set_shutdown is called on the fd */
         if (gpr_atm_rel_cas(state, curr, new_state)) {
-          grpc_closure_sched(
-              exec_ctx, (grpc_closure *)curr,
-              GRPC_ERROR_CREATE_REFERENCING("FD Shutdown", &shutdown_err, 1));
+          grpc_closure_sched(exec_ctx, (grpc_closure *)curr,
+                             GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                                 "FD Shutdown", &shutdown_err, 1));
           return;
         }
 
diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c
index 789ef22..ca6e855 100644
--- a/src/core/lib/iomgr/ev_poll_posix.c
+++ b/src/core/lib/iomgr/ev_poll_posix.c
@@ -451,14 +451,16 @@
   if (!fd->shutdown) {
     return GRPC_ERROR_NONE;
   } else {
-    return GRPC_ERROR_CREATE_REFERENCING("FD shutdown", &fd->shutdown_error, 1);
+    return GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+        "FD shutdown", &fd->shutdown_error, 1);
   }
 }
 
 static void notify_on_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
                              grpc_closure **st, grpc_closure *closure) {
   if (fd->shutdown) {
-    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE("FD shutdown"));
+    grpc_closure_sched(exec_ctx, closure,
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING("FD shutdown"));
   } else if (*st == CLOSURE_NOT_READY) {
     /* not ready ==> switch to a waiting state by setting the closure */
     *st = closure;
@@ -696,7 +698,7 @@
 static void kick_append_error(grpc_error **composite, grpc_error *error) {
   if (error == GRPC_ERROR_NONE) return;
   if (*composite == GRPC_ERROR_NONE) {
-    *composite = GRPC_ERROR_CREATE("Kick Failure");
+    *composite = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Kick Failure");
   }
   *composite = grpc_error_add_child(*composite, error);
 }
@@ -859,7 +861,7 @@
 static void work_combine_error(grpc_error **composite, grpc_error *error) {
   if (error == GRPC_ERROR_NONE) return;
   if (*composite == GRPC_ERROR_NONE) {
-    *composite = GRPC_ERROR_CREATE("pollset_work");
+    *composite = GRPC_ERROR_CREATE_FROM_STATIC_STRING("pollset_work");
   }
   *composite = grpc_error_add_child(*composite, error);
 }
diff --git a/src/core/lib/iomgr/load_file.c b/src/core/lib/iomgr/load_file.c
index f40c8b2..208f74e 100644
--- a/src/core/lib/iomgr/load_file.c
+++ b/src/core/lib/iomgr/load_file.c
@@ -78,9 +78,12 @@
   *output = result;
   if (file != NULL) fclose(file);
   if (error != GRPC_ERROR_NONE) {
-    grpc_error *error_out = grpc_error_set_str(
-        GRPC_ERROR_CREATE_REFERENCING("Failed to load file", &error, 1),
-        GRPC_ERROR_STR_FILENAME, filename);
+    grpc_error *error_out =
+        grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                               "Failed to load file", &error, 1),
+                           GRPC_ERROR_STR_FILENAME,
+                           grpc_slice_from_copied_string(
+                               filename));  // TODO(ncteisen), always static?
     GRPC_ERROR_UNREF(error);
     error = error_out;
   }
diff --git a/src/core/lib/iomgr/resolve_address_posix.c b/src/core/lib/iomgr/resolve_address_posix.c
index 50e470d..d0ede0f 100644
--- a/src/core/lib/iomgr/resolve_address_posix.c
+++ b/src/core/lib/iomgr/resolve_address_posix.c
@@ -73,14 +73,16 @@
   /* parse name, splitting it into host and port parts */
   gpr_split_host_port(name, &host, &port);
   if (host == NULL) {
-    err = grpc_error_set_str(GRPC_ERROR_CREATE("unparseable host:port"),
-                             GRPC_ERROR_STR_TARGET_ADDRESS, name);
+    err = grpc_error_set_str(
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("unparseable host:port"),
+        GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
     goto done;
   }
   if (port == NULL) {
     if (default_port == NULL) {
-      err = grpc_error_set_str(GRPC_ERROR_CREATE("no port in name"),
-                               GRPC_ERROR_STR_TARGET_ADDRESS, name);
+      err = grpc_error_set_str(
+          GRPC_ERROR_CREATE_FROM_STATIC_STRING("no port in name"),
+          GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
       goto done;
     }
     port = gpr_strdup(default_port);
@@ -112,11 +114,15 @@
   if (s != 0) {
     err = grpc_error_set_str(
         grpc_error_set_str(
-            grpc_error_set_str(grpc_error_set_int(GRPC_ERROR_CREATE("OS Error"),
-                                                  GRPC_ERROR_INT_ERRNO, s),
-                               GRPC_ERROR_STR_OS_ERROR, gai_strerror(s)),
-            GRPC_ERROR_STR_SYSCALL, "getaddrinfo"),
-        GRPC_ERROR_STR_TARGET_ADDRESS, name);
+            grpc_error_set_str(
+                grpc_error_set_int(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("OS Error"),
+                    GRPC_ERROR_INT_ERRNO, s),
+                GRPC_ERROR_STR_OS_ERROR,
+                grpc_slice_from_static_string(gai_strerror(s))),
+            GRPC_ERROR_STR_SYSCALL,
+            grpc_slice_from_static_string("getaddrinfo")),
+        GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
     goto done;
   }
 
diff --git a/src/core/lib/iomgr/resolve_address_uv.c b/src/core/lib/iomgr/resolve_address_uv.c
index 4d715be..102d1aa 100644
--- a/src/core/lib/iomgr/resolve_address_uv.c
+++ b/src/core/lib/iomgr/resolve_address_uv.c
@@ -92,9 +92,10 @@
   if (status != 0) {
     grpc_error *error;
     *addresses = NULL;
-    error = GRPC_ERROR_CREATE("getaddrinfo failed");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("getaddrinfo failed");
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
     return error;
   }
   (*addresses) = gpr_malloc(sizeof(grpc_resolved_addresses));
@@ -153,7 +154,7 @@
   if (*host == NULL) {
     char *msg;
     gpr_asprintf(&msg, "unparseable host:port: '%s'", name);
-    error = GRPC_ERROR_CREATE(msg);
+    error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return error;
   }
@@ -162,7 +163,7 @@
     if (default_port == NULL) {
       char *msg;
       gpr_asprintf(&msg, "no port in name '%s'", name);
-      error = GRPC_ERROR_CREATE(msg);
+      error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
       gpr_free(msg);
       return error;
     }
@@ -262,8 +263,9 @@
 
   if (s != 0) {
     *addrs = NULL;
-    err = GRPC_ERROR_CREATE("getaddrinfo failed");
-    err = grpc_error_set_str(err, GRPC_ERROR_STR_OS_ERROR, uv_strerror(s));
+    err = GRPC_ERROR_CREATE_FROM_STATIC_STRING("getaddrinfo failed");
+    err = grpc_error_set_str(err, GRPC_ERROR_STR_OS_ERROR,
+                             grpc_slice_from_static_string(uv_strerror(s)));
     grpc_closure_sched(exec_ctx, on_done, err);
     gpr_free(r);
     gpr_free(req);
diff --git a/src/core/lib/iomgr/resolve_address_windows.c b/src/core/lib/iomgr/resolve_address_windows.c
index 2439ce3..22eca1f 100644
--- a/src/core/lib/iomgr/resolve_address_windows.c
+++ b/src/core/lib/iomgr/resolve_address_windows.c
@@ -78,7 +78,7 @@
   if (host == NULL) {
     char *msg;
     gpr_asprintf(&msg, "unparseable host:port: '%s'", name);
-    error = GRPC_ERROR_CREATE(msg);
+    error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     goto done;
   }
@@ -86,7 +86,7 @@
     if (default_port == NULL) {
       char *msg;
       gpr_asprintf(&msg, "no port in name '%s'", name);
-      error = GRPC_ERROR_CREATE(msg);
+      error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
       gpr_free(msg);
       goto done;
     }
diff --git a/src/core/lib/iomgr/socket_utils_common_posix.c b/src/core/lib/iomgr/socket_utils_common_posix.c
index 88e9ade..b69c924 100644
--- a/src/core/lib/iomgr/socket_utils_common_posix.c
+++ b/src/core/lib/iomgr/socket_utils_common_posix.c
@@ -90,7 +90,7 @@
     return GRPC_OS_ERROR(errno, "getsockopt(SO_NOSIGPIPE)");
   }
   if ((newval != 0) != (val != 0)) {
-    return GRPC_ERROR_CREATE("Failed to set SO_NOSIGPIPE");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_NOSIGPIPE");
   }
 #endif
   return GRPC_ERROR_NONE;
@@ -164,7 +164,7 @@
     return GRPC_OS_ERROR(errno, "getsockopt(SO_REUSEADDR)");
   }
   if ((newval != 0) != val) {
-    return GRPC_ERROR_CREATE("Failed to set SO_REUSEADDR");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_REUSEADDR");
   }
 
   return GRPC_ERROR_NONE;
@@ -173,7 +173,8 @@
 /* set a socket to reuse old addresses */
 grpc_error *grpc_set_socket_reuse_port(int fd, int reuse) {
 #ifndef SO_REUSEPORT
-  return GRPC_ERROR_CREATE("SO_REUSEPORT unavailable on compiling system");
+  return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+      "SO_REUSEPORT unavailable on compiling system");
 #else
   int val = (reuse != 0);
   int newval;
@@ -185,7 +186,7 @@
     return GRPC_OS_ERROR(errno, "getsockopt(SO_REUSEPORT)");
   }
   if ((newval != 0) != val) {
-    return GRPC_ERROR_CREATE("Failed to set SO_REUSEPORT");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_REUSEPORT");
   }
 
   return GRPC_ERROR_NONE;
@@ -204,7 +205,7 @@
     return GRPC_OS_ERROR(errno, "getsockopt(TCP_NODELAY)");
   }
   if ((newval != 0) != val) {
-    return GRPC_ERROR_CREATE("Failed to set TCP_NODELAY");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set TCP_NODELAY");
   }
   return GRPC_ERROR_NONE;
 }
@@ -213,7 +214,7 @@
 grpc_error *grpc_set_socket_with_mutator(int fd, grpc_socket_mutator *mutator) {
   GPR_ASSERT(mutator);
   if (!grpc_socket_mutator_mutate_fd(mutator, fd)) {
-    return GRPC_ERROR_CREATE("grpc_socket_mutator failed.");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("grpc_socket_mutator failed.");
   }
   return GRPC_ERROR_NONE;
 }
@@ -268,7 +269,8 @@
   char *addr_str;
   grpc_sockaddr_to_string(&addr_str, addr, 0);
   grpc_error *err = grpc_error_set_str(GRPC_OS_ERROR(errno, "socket"),
-                                       GRPC_ERROR_STR_TARGET_ADDRESS, addr_str);
+                                       GRPC_ERROR_STR_TARGET_ADDRESS,
+                                       grpc_slice_from_copied_string(addr_str));
   gpr_free(addr_str);
   return err;
 }
diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c
index 0144192..a108b10 100644
--- a/src/core/lib/iomgr/tcp_client_posix.c
+++ b/src/core/lib/iomgr/tcp_client_posix.c
@@ -121,8 +121,8 @@
   }
   gpr_mu_lock(&ac->mu);
   if (ac->fd != NULL) {
-    grpc_fd_shutdown(exec_ctx, ac->fd,
-                     GRPC_ERROR_CREATE("connect() timed out"));
+    grpc_fd_shutdown(exec_ctx, ac->fd, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                           "connect() timed out"));
   }
   done = (--ac->refs == 0);
   gpr_mu_unlock(&ac->mu);
@@ -191,7 +191,8 @@
   gpr_mu_lock(&ac->mu);
   if (error != GRPC_ERROR_NONE) {
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, "Timeout occurred");
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string("Timeout occurred"));
     goto finish;
   }
 
@@ -252,12 +253,17 @@
   gpr_mu_unlock(&ac->mu);
   if (error != GRPC_ERROR_NONE) {
     char *error_descr;
-    gpr_asprintf(&error_descr, "Failed to connect to remote host: %s",
-                 grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION));
-    error = grpc_error_set_str(error, GRPC_ERROR_STR_DESCRIPTION, error_descr);
+    grpc_slice str;
+    bool ret = grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION, &str);
+    GPR_ASSERT(ret);
+    char *desc = grpc_slice_to_c_string(str);
+    gpr_asprintf(&error_descr, "Failed to connect to remote host: %s", desc);
+    error = grpc_error_set_str(error, GRPC_ERROR_STR_DESCRIPTION,
+                               grpc_slice_from_copied_string(error_descr));
     gpr_free(error_descr);
-    error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, ac->addr_str);
+    gpr_free(desc);
+    error = grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS,
+                               grpc_slice_from_copied_string(ac->addr_str));
   }
   if (done) {
     gpr_mu_destroy(&ac->mu);
diff --git a/src/core/lib/iomgr/tcp_client_uv.c b/src/core/lib/iomgr/tcp_client_uv.c
index 618483d..682c24e 100644
--- a/src/core/lib/iomgr/tcp_client_uv.c
+++ b/src/core/lib/iomgr/tcp_client_uv.c
@@ -100,17 +100,21 @@
     *connect->endpoint = grpc_tcp_create(
         connect->tcp_handle, connect->resource_quota, connect->addr_name);
   } else {
-    error = GRPC_ERROR_CREATE("Failed to connect to remote host");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Failed to connect to remote host");
     error = grpc_error_set_int(error, GRPC_ERROR_INT_ERRNO, -status);
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
     if (status == UV_ECANCELED) {
-      error = grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
-                                 "Timeout occurred");
+      error =
+          grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                             grpc_slice_from_static_string("Timeout occurred"));
       // This should only happen if the handle is already closed
     } else {
-      error = grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
-                                 uv_strerror(status));
+      error = grpc_error_set_str(
+          error, GRPC_ERROR_STR_OS_ERROR,
+          grpc_slice_from_static_string(uv_strerror(status)));
       uv_close((uv_handle_t *)connect->tcp_handle, tcp_close_callback);
     }
   }
diff --git a/src/core/lib/iomgr/tcp_client_windows.c b/src/core/lib/iomgr/tcp_client_windows.c
index c8dc9e6..a356564 100644
--- a/src/core/lib/iomgr/tcp_client_windows.c
+++ b/src/core/lib/iomgr/tcp_client_windows.c
@@ -123,7 +123,7 @@
         socket = NULL;
       }
     } else {
-      error = GRPC_ERROR_CREATE("socket is null");
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("socket is null");
     }
   }
 
@@ -238,8 +238,9 @@
   GPR_ASSERT(error != GRPC_ERROR_NONE);
   char *target_uri = grpc_sockaddr_to_uri(addr);
   grpc_error *final_error = grpc_error_set_str(
-      GRPC_ERROR_CREATE_REFERENCING("Failed to connect", &error, 1),
-      GRPC_ERROR_STR_TARGET_ADDRESS, target_uri);
+      GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Failed to connect",
+                                                       &error, 1),
+      GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(target_uri));
   GRPC_ERROR_UNREF(error);
   if (socket != NULL) {
     grpc_winsocket_destroy(socket);
diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c
index a4381f8..4d7cf3f 100644
--- a/src/core/lib/iomgr/tcp_posix.c
+++ b/src/core/lib/iomgr/tcp_posix.c
@@ -111,7 +111,8 @@
 static grpc_error *tcp_annotate_error(grpc_error *src_error, grpc_tcp *tcp) {
   return grpc_error_set_str(
       grpc_error_set_int(src_error, GRPC_ERROR_INT_FD, tcp->fd),
-      GRPC_ERROR_STR_TARGET_ADDRESS, tcp->peer_string);
+      GRPC_ERROR_STR_TARGET_ADDRESS,
+      grpc_slice_from_copied_string(tcp->peer_string));
 }
 
 static void tcp_handle_read(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */,
@@ -246,8 +247,10 @@
   } else if (read_bytes == 0) {
     /* 0 read size ==> end of stream */
     grpc_slice_buffer_reset_and_unref_internal(exec_ctx, tcp->incoming_buffer);
-    call_read_cb(exec_ctx, tcp,
-                 tcp_annotate_error(GRPC_ERROR_CREATE("Socket closed"), tcp));
+    call_read_cb(
+        exec_ctx, tcp,
+        tcp_annotate_error(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Socket closed"), tcp));
     TCP_UNREF(exec_ctx, tcp, "read");
   } else {
     GPR_ASSERT((size_t)read_bytes <= tcp->incoming_buffer->length);
@@ -464,10 +467,12 @@
 
   if (buf->length == 0) {
     GPR_TIMER_END("tcp_write", 0);
-    grpc_closure_sched(exec_ctx, cb,
-                       grpc_fd_is_shutdown(tcp->em_fd)
-                           ? tcp_annotate_error(GRPC_ERROR_CREATE("EOF"), tcp)
-                           : GRPC_ERROR_NONE);
+    grpc_closure_sched(
+        exec_ctx, cb,
+        grpc_fd_is_shutdown(tcp->em_fd)
+            ? tcp_annotate_error(GRPC_ERROR_CREATE_FROM_STATIC_STRING("EOF"),
+                                 tcp)
+            : GRPC_ERROR_NONE);
     return;
   }
   tcp->outgoing_buffer = buf;
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c
index e242631..e1efbd4 100644
--- a/src/core/lib/iomgr/tcp_server_posix.c
+++ b/src/core/lib/iomgr/tcp_server_posix.c
@@ -100,8 +100,8 @@
       } else {
         grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
-        return GRPC_ERROR_CREATE(GRPC_ARG_ALLOW_REUSEPORT
-                                 " must be an integer");
+        return GRPC_ERROR_CREATE_FROM_STATIC_STRING(GRPC_ARG_ALLOW_REUSEPORT
+                                                    " must be an integer");
       }
     } else if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
       if (args->args[i].type == GRPC_ARG_POINTER) {
@@ -111,8 +111,8 @@
       } else {
         grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
-        return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
-                                 " must be a pointer to a buffer pool");
+        return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+            GRPC_ARG_RESOURCE_QUOTA " must be a pointer to a buffer pool");
       }
     } else if (0 == strcmp(GRPC_ARG_EXPAND_WILDCARD_ADDRS, args->args[i].key)) {
       if (args->args[i].type == GRPC_ARG_INTEGER) {
@@ -120,8 +120,8 @@
       } else {
         grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
-        return GRPC_ERROR_CREATE(GRPC_ARG_EXPAND_WILDCARD_ADDRS
-                                 " must be an integer");
+        return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+            GRPC_ARG_EXPAND_WILDCARD_ADDRS " must be an integer");
       }
     }
   }
@@ -216,8 +216,8 @@
   if (s->active_ports) {
     grpc_tcp_listener *sp;
     for (sp = s->head; sp; sp = sp->next) {
-      grpc_fd_shutdown(exec_ctx, sp->emfd,
-                       GRPC_ERROR_CREATE("Server destroyed"));
+      grpc_fd_shutdown(exec_ctx, sp->emfd, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                               "Server destroyed"));
     }
     gpr_mu_unlock(&s->mu);
   } else {
@@ -366,8 +366,8 @@
     }
     return GRPC_ERROR_NONE;
   } else {
-    grpc_error *root_err =
-        GRPC_ERROR_CREATE("Failed to add any wildcard listeners");
+    grpc_error *root_err = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Failed to add any wildcard listeners");
     GPR_ASSERT(v6_err != GRPC_ERROR_NONE && v4_err != GRPC_ERROR_NONE);
     root_err = grpc_error_add_child(root_err, v6_err);
     root_err = grpc_error_add_child(root_err, v4_err);
@@ -587,7 +587,7 @@
     grpc_tcp_listener *sp;
     for (sp = s->head; sp; sp = sp->next) {
       grpc_fd_shutdown(exec_ctx, sp->emfd,
-                       GRPC_ERROR_CREATE("Server shutdown"));
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server shutdown"));
     }
   }
   gpr_mu_unlock(&s->mu);
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_common.c b/src/core/lib/iomgr/tcp_server_utils_posix_common.c
index e45e27d..283b92b 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix_common.c
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.c
@@ -210,9 +210,10 @@
   if (fd >= 0) {
     close(fd);
   }
-  grpc_error *ret = grpc_error_set_int(
-      GRPC_ERROR_CREATE_REFERENCING("Unable to configure socket", &err, 1),
-      GRPC_ERROR_INT_FD, fd);
+  grpc_error *ret =
+      grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                             "Unable to configure socket", &err, 1),
+                         GRPC_ERROR_INT_FD, fd);
   GRPC_ERROR_UNREF(err);
   return ret;
 }
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c b/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
index 6354a6b..2078a68 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c
@@ -94,7 +94,8 @@
   }
   close(fd);
   *port = grpc_sockaddr_get_port(&wild);
-  return *port <= 0 ? GRPC_ERROR_CREATE("Bad port") : GRPC_ERROR_NONE;
+  return *port <= 0 ? GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad port")
+                    : GRPC_ERROR_NONE;
 }
 
 grpc_error *grpc_tcp_server_add_all_local_addrs(grpc_tcp_server *s,
@@ -114,7 +115,7 @@
     if ((err = get_unused_port(&requested_port)) != GRPC_ERROR_NONE) {
       return err;
     } else if (requested_port <= 0) {
-      return GRPC_ERROR_CREATE("Bad get_unused_port()");
+      return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad get_unused_port()");
     }
     gpr_log(GPR_DEBUG, "Picked unused port %d", requested_port);
   }
@@ -139,7 +140,7 @@
     memcpy(addr.addr, ifa_it->ifa_addr, addr.len);
     if (!grpc_sockaddr_set_port(&addr, requested_port)) {
       /* Should never happen, because we check sa_family above. */
-      err = GRPC_ERROR_CREATE("Failed to set port");
+      err = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set port");
       break;
     }
     if (grpc_sockaddr_to_string(&addr_str, &addr, 0) < 0) {
@@ -163,7 +164,7 @@
       if (gpr_asprintf(&err_str, "Failed to add listener: %s", addr_str) < 0) {
         err_str = gpr_strdup("Failed to add listener");
       }
-      root_err = GRPC_ERROR_CREATE(err_str);
+      root_err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(err_str);
       gpr_free(err_str);
       gpr_free(addr_str);
       err = grpc_error_add_child(root_err, err);
@@ -183,7 +184,7 @@
   if (err != GRPC_ERROR_NONE) {
     return err;
   } else if (sp == NULL) {
-    return GRPC_ERROR_CREATE("No local addresses");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("No local addresses");
   } else {
     *out_port = sp->port;
     return GRPC_ERROR_NONE;
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c b/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
index 95c3198..d6a1a06 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c
@@ -41,7 +41,7 @@
                                                 unsigned port_index,
                                                 int requested_port,
                                                 int *out_port) {
-  return GRPC_ERROR_CREATE("no ifaddrs available");
+  return GRPC_ERROR_CREATE_FROM_STATIC_STRING("no ifaddrs available");
 }
 
 bool grpc_tcp_server_have_ifaddrs(void) { return false; }
diff --git a/src/core/lib/iomgr/tcp_server_uv.c b/src/core/lib/iomgr/tcp_server_uv.c
index eed2773..e924694 100644
--- a/src/core/lib/iomgr/tcp_server_uv.c
+++ b/src/core/lib/iomgr/tcp_server_uv.c
@@ -95,8 +95,8 @@
       } else {
         grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
-        return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
-                                 " must be a pointer to a buffer pool");
+        return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+            GRPC_ARG_RESOURCE_QUOTA " must be a pointer to a buffer pool");
       }
     }
   }
@@ -244,17 +244,19 @@
   // The last argument to uv_tcp_bind is flags
   status = uv_tcp_bind(handle, (struct sockaddr *)addr->addr, 0);
   if (status != 0) {
-    error = GRPC_ERROR_CREATE("Failed to bind to port");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to bind to port");
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
     return error;
   }
 
   status = uv_listen((uv_stream_t *)handle, SOMAXCONN, on_connect);
   if (status != 0) {
-    error = GRPC_ERROR_CREATE("Failed to listen to port");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to listen to port");
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
     return error;
   }
 
@@ -262,9 +264,10 @@
   status = uv_tcp_getsockname(handle, (struct sockaddr *)&sockname_temp.addr,
                               (int *)&sockname_temp.len);
   if (status != 0) {
-    error = GRPC_ERROR_CREATE("getsockname failed");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("getsockname failed");
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
     return error;
   }
 
@@ -346,15 +349,17 @@
   if (status == 0) {
     error = add_socket_to_server(s, handle, addr, port_index, &sp);
   } else {
-    error = GRPC_ERROR_CREATE("Failed to initialize UV tcp handle");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Failed to initialize UV tcp handle");
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
   }
 
   gpr_free(allocated_addr);
 
   if (error != GRPC_ERROR_NONE) {
-    grpc_error *error_out = GRPC_ERROR_CREATE_REFERENCING(
+    grpc_error *error_out = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
         "Failed to add port to server", &error, 1);
     GRPC_ERROR_UNREF(error);
     error = error_out;
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index bd4b9b2..12ce7d3 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -122,8 +122,8 @@
       } else {
         grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
-        return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
-                                 " must be a pointer to a buffer pool");
+        return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+            GRPC_ARG_RESOURCE_QUOTA " must be a pointer to a buffer pool");
       }
     }
   }
@@ -248,9 +248,10 @@
   GPR_ASSERT(error != GRPC_ERROR_NONE);
   char *tgtaddr = grpc_sockaddr_to_uri(addr);
   grpc_error_set_int(
-      grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING(
+      grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
                              "Failed to prepare server socket", &error, 1),
-                         GRPC_ERROR_STR_TARGET_ADDRESS, tgtaddr),
+                         GRPC_ERROR_STR_TARGET_ADDRESS,
+                         grpc_slice_from_copied_string(tgtaddr)),
       GRPC_ERROR_INT_FD, (intptr_t)sock);
   gpr_free(tgtaddr);
   GRPC_ERROR_UNREF(error);
@@ -533,7 +534,7 @@
   gpr_free(allocated_addr);
 
   if (error != GRPC_ERROR_NONE) {
-    grpc_error *error_out = GRPC_ERROR_CREATE_REFERENCING(
+    grpc_error *error_out = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
         "Failed to add port to server", &error, 1);
     GRPC_ERROR_UNREF(error);
     error = error_out;
diff --git a/src/core/lib/iomgr/tcp_uv.c b/src/core/lib/iomgr/tcp_uv.c
index 5541c62..8e8db9f 100644
--- a/src/core/lib/iomgr/tcp_uv.c
+++ b/src/core/lib/iomgr/tcp_uv.c
@@ -152,7 +152,7 @@
   // TODO(murgatroid99): figure out what the return value here means
   uv_read_stop(stream);
   if (nread == UV_EOF) {
-    error = GRPC_ERROR_CREATE("EOF");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("EOF");
   } else if (nread > 0) {
     // Successful read
     sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, (size_t)nread);
@@ -173,7 +173,7 @@
     }
   } else {
     // nread < 0: Error
-    error = GRPC_ERROR_CREATE("TCP Read failed");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("TCP Read failed");
   }
   grpc_closure_sched(&exec_ctx, cb, error);
   grpc_exec_ctx_finish(&exec_ctx);
@@ -193,9 +193,10 @@
   status =
       uv_read_start((uv_stream_t *)tcp->handle, alloc_uv_buf, read_callback);
   if (status != 0) {
-    error = GRPC_ERROR_CREATE("TCP Read failed at start");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("TCP Read failed at start");
     error =
-        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
+        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
+                           grpc_slice_from_static_string(uv_strerror(status)));
     grpc_closure_sched(exec_ctx, cb, error);
   }
   if (grpc_tcp_trace) {
@@ -214,7 +215,7 @@
   if (status == 0) {
     error = GRPC_ERROR_NONE;
   } else {
-    error = GRPC_ERROR_CREATE("TCP Write failed");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("TCP Write failed");
   }
   if (grpc_tcp_trace) {
     const char *str = grpc_error_string(error);
@@ -249,8 +250,8 @@
   }
 
   if (tcp->shutting_down) {
-    grpc_closure_sched(exec_ctx, cb,
-                       GRPC_ERROR_CREATE("TCP socket is shutting down"));
+    grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                         "TCP socket is shutting down"));
     return;
   }
 
diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c
index 6c41397..9134883 100644
--- a/src/core/lib/iomgr/tcp_windows.c
+++ b/src/core/lib/iomgr/tcp_windows.c
@@ -175,7 +175,7 @@
   if (error == GRPC_ERROR_NONE) {
     if (info->wsa_error != 0 && !tcp->shutting_down) {
       char *utf8_message = gpr_format_message(info->wsa_error);
-      error = GRPC_ERROR_CREATE(utf8_message);
+      error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(utf8_message);
       gpr_free(utf8_message);
       grpc_slice_unref_internal(exec_ctx, tcp->read_slice);
     } else {
@@ -185,9 +185,9 @@
       } else {
         grpc_slice_unref_internal(exec_ctx, tcp->read_slice);
         error = tcp->shutting_down
-                    ? GRPC_ERROR_CREATE_REFERENCING("TCP stream shutting down",
-                                                    &tcp->shutdown_error, 1)
-                    : GRPC_ERROR_CREATE("End of TCP stream");
+                    ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                          "TCP stream shutting down", &tcp->shutdown_error, 1)
+                    : GRPC_ERROR_CREATE_FROM_STATIC_STRING("End of TCP stream");
       }
     }
   }
@@ -208,9 +208,10 @@
   WSABUF buffer;
 
   if (tcp->shutting_down) {
-    grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_CREATE_REFERENCING(
-                                         "TCP socket is shutting down",
-                                         &tcp->shutdown_error, 1));
+    grpc_closure_sched(
+        exec_ctx, cb,
+        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+            "TCP socket is shutting down", &tcp->shutdown_error, 1));
     return;
   }
 
@@ -297,9 +298,10 @@
   size_t len;
 
   if (tcp->shutting_down) {
-    grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_CREATE_REFERENCING(
-                                         "TCP socket is shutting down",
-                                         &tcp->shutdown_error, 1));
+    grpc_closure_sched(
+        exec_ctx, cb,
+        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+            "TCP socket is shutting down", &tcp->shutdown_error, 1));
     return;
   }
 
diff --git a/src/core/lib/iomgr/timer_generic.c b/src/core/lib/iomgr/timer_generic.c
index d4df96c..e53c801 100644
--- a/src/core/lib/iomgr/timer_generic.c
+++ b/src/core/lib/iomgr/timer_generic.c
@@ -109,8 +109,9 @@
 
 void grpc_timer_list_shutdown(grpc_exec_ctx *exec_ctx) {
   int i;
-  run_some_expired_timers(exec_ctx, gpr_inf_future(g_clock_type), NULL,
-                          GRPC_ERROR_CREATE("Timer list shutdown"));
+  run_some_expired_timers(
+      exec_ctx, gpr_inf_future(g_clock_type), NULL,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Timer list shutdown"));
   for (i = 0; i < NUM_SHARDS; i++) {
     shard_type *shard = &g_shards[i];
     gpr_mu_destroy(&shard->mu);
@@ -182,9 +183,9 @@
 
   if (!g_initialized) {
     timer->pending = false;
-    grpc_closure_sched(
-        exec_ctx, timer->closure,
-        GRPC_ERROR_CREATE("Attempt to create timer before initialization"));
+    grpc_closure_sched(exec_ctx, timer->closure,
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                           "Attempt to create timer before initialization"));
     return;
   }
 
@@ -376,7 +377,7 @@
       exec_ctx, now, next,
       gpr_time_cmp(now, gpr_inf_future(now.clock_type)) != 0
           ? GRPC_ERROR_NONE
-          : GRPC_ERROR_CREATE("Shutting down timer system"));
+          : GRPC_ERROR_CREATE_FROM_STATIC_STRING("Shutting down timer system"));
 }
 
 #endif /* GRPC_TIMER_USE_GENERIC */
diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c
index 71e2957..28f2bd9 100644
--- a/src/core/lib/iomgr/udp_server.c
+++ b/src/core/lib/iomgr/udp_server.c
@@ -205,8 +205,8 @@
     for (sp = s->head; sp; sp = sp->next) {
       GPR_ASSERT(sp->orphan_cb);
       sp->orphan_cb(exec_ctx, sp->emfd, sp->server->user_data);
-      grpc_fd_shutdown(exec_ctx, sp->emfd,
-                       GRPC_ERROR_CREATE("Server destroyed"));
+      grpc_fd_shutdown(exec_ctx, sp->emfd, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                               "Server destroyed"));
     }
     gpr_mu_unlock(&s->mu);
   } else {
diff --git a/src/core/lib/iomgr/unix_sockets_posix.c b/src/core/lib/iomgr/unix_sockets_posix.c
index 1233cec..281865a 100644
--- a/src/core/lib/iomgr/unix_sockets_posix.c
+++ b/src/core/lib/iomgr/unix_sockets_posix.c
@@ -60,7 +60,7 @@
     gpr_asprintf(&err_msg,
                  "Path name should not have more than %" PRIuPTR " characters.",
                  GPR_ARRAY_SIZE(un->sun_path) - 1);
-    err = GRPC_ERROR_CREATE(err_msg);
+    err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(err_msg);
     gpr_free(err_msg);
     return err;
   }
diff --git a/src/core/lib/iomgr/unix_sockets_posix_noop.c b/src/core/lib/iomgr/unix_sockets_posix_noop.c
index 1daf515..b9602cb 100644
--- a/src/core/lib/iomgr/unix_sockets_posix_noop.c
+++ b/src/core/lib/iomgr/unix_sockets_posix_noop.c
@@ -47,7 +47,8 @@
 grpc_error *grpc_resolve_unix_domain_address(
     const char *name, grpc_resolved_addresses **addresses) {
   *addresses = NULL;
-  return GRPC_ERROR_CREATE("Unix domain sockets are not supported on Windows");
+  return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+      "Unix domain sockets are not supported on Windows");
 }
 
 int grpc_is_unix_socket(const grpc_resolved_address *addr) { return false; }
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.c b/src/core/lib/security/credentials/google_default/google_default_credentials.c
index dd44621..97501e6 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.c
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.c
@@ -180,7 +180,7 @@
   grpc_slice creds_data = grpc_empty_slice();
   grpc_error *error = GRPC_ERROR_NONE;
   if (creds_path == NULL) {
-    error = GRPC_ERROR_CREATE("creds_path unset");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("creds_path unset");
     goto end;
   }
   error = grpc_load_file(creds_path, 0, &creds_data);
@@ -190,10 +190,9 @@
   json = grpc_json_parse_string_with_len(
       (char *)GRPC_SLICE_START_PTR(creds_data), GRPC_SLICE_LENGTH(creds_data));
   if (json == NULL) {
-    char *dump = grpc_dump_slice(creds_data, GPR_DUMP_HEX | GPR_DUMP_ASCII);
-    error = grpc_error_set_str(GRPC_ERROR_CREATE("Failed to parse JSON"),
-                               GRPC_ERROR_STR_RAW_BYTES, dump);
-    gpr_free(dump);
+    error = grpc_error_set_str(
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to parse JSON"),
+        GRPC_ERROR_STR_RAW_BYTES, grpc_slice_ref_internal(creds_data));
     goto end;
   }
 
@@ -204,7 +203,7 @@
         grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
             exec_ctx, key, grpc_max_auth_token_lifetime());
     if (result == NULL) {
-      error = GRPC_ERROR_CREATE(
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
           "grpc_service_account_jwt_access_credentials_create_from_auth_json_"
           "key failed");
     }
@@ -217,7 +216,7 @@
     result =
         grpc_refresh_token_credentials_create_from_auth_refresh_token(token);
     if (result == NULL) {
-      error = GRPC_ERROR_CREATE(
+      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
           "grpc_refresh_token_credentials_create_from_auth_refresh_token "
           "failed");
     }
@@ -236,7 +235,8 @@
 grpc_channel_credentials *grpc_google_default_credentials_create(void) {
   grpc_channel_credentials *result = NULL;
   grpc_call_credentials *call_creds = NULL;
-  grpc_error *error = GRPC_ERROR_CREATE("Failed to create Google credentials");
+  grpc_error *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+      "Failed to create Google credentials");
   grpc_error *err;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
@@ -274,7 +274,8 @@
       call_creds = grpc_google_compute_engine_credentials_create(NULL);
       if (call_creds == NULL) {
         error = grpc_error_add_child(
-            error, GRPC_ERROR_CREATE("Failed to get credentials from network"));
+            error, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                       "Failed to get credentials from network"));
       }
     }
   }
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index 8dea1d9..8f321b9 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -95,7 +95,8 @@
 static void add_error(grpc_error **combined, grpc_error *error) {
   if (error == GRPC_ERROR_NONE) return;
   if (*combined == GRPC_ERROR_NONE) {
-    *combined = GRPC_ERROR_CREATE("Client auth metadata plugin error");
+    *combined = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Client auth metadata plugin error");
   }
   *combined = grpc_error_add_child(*combined, error);
 }
@@ -114,9 +115,10 @@
   grpc_error *error = GRPC_ERROR_NONE;
   if (status != GRPC_CREDENTIALS_OK) {
     error = grpc_error_set_int(
-        GRPC_ERROR_CREATE(error_details != NULL && strlen(error_details) > 0
-                              ? error_details
-                              : "Credentials failed to get metadata."),
+        GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+            error_details != NULL && strlen(error_details) > 0
+                ? error_details
+                : "Credentials failed to get metadata."),
         GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAUTHENTICATED);
   } else {
     GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT);
@@ -192,7 +194,7 @@
       grpc_transport_stream_op_finish_with_failure(
           exec_ctx, op,
           grpc_error_set_int(
-              GRPC_ERROR_CREATE(
+              GRPC_ERROR_CREATE_FROM_STATIC_STRING(
                   "Incompatible credentials set on channel and call."),
               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAUTHENTICATED));
       return;
@@ -225,9 +227,10 @@
                  host);
     gpr_free(host);
     grpc_call_element_signal_error(
-        exec_ctx, elem, grpc_error_set_int(GRPC_ERROR_CREATE(error_msg),
-                                           GRPC_ERROR_INT_GRPC_STATUS,
-                                           GRPC_STATUS_UNAUTHENTICATED));
+        exec_ctx, elem,
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg),
+                           GRPC_ERROR_INT_GRPC_STATUS,
+                           GRPC_STATUS_UNAUTHENTICATED));
     gpr_free(error_msg);
   }
 }
diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c
index 7d58843..568d70f 100644
--- a/src/core/lib/security/transport/secure_endpoint.c
+++ b/src/core/lib/security/transport/secure_endpoint.c
@@ -162,7 +162,7 @@
 
   if (error != GRPC_ERROR_NONE) {
     grpc_slice_buffer_reset_and_unref_internal(exec_ctx, ep->read_buffer);
-    call_read_cb(exec_ctx, ep, GRPC_ERROR_CREATE_REFERENCING(
+    call_read_cb(exec_ctx, ep, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
                                    "Secure read failed", &error, 1));
     return;
   }
@@ -220,8 +220,10 @@
 
   if (result != TSI_OK) {
     grpc_slice_buffer_reset_and_unref_internal(exec_ctx, ep->read_buffer);
-    call_read_cb(exec_ctx, ep, grpc_set_tsi_error_result(
-                                   GRPC_ERROR_CREATE("Unwrap failed"), result));
+    call_read_cb(
+        exec_ctx, ep,
+        grpc_set_tsi_error_result(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Unwrap failed"), result));
     return;
   }
 
@@ -332,7 +334,8 @@
     grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &ep->output_buffer);
     grpc_closure_sched(
         exec_ctx, cb,
-        grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Wrap failed"), result));
+        grpc_set_tsi_error_result(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Wrap failed"), result));
     GPR_TIMER_END("secure_endpoint.endpoint_write", 0);
     return;
   }
diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.c
index ad083a7..b0cbc83 100644
--- a/src/core/lib/security/transport/security_connector.c
+++ b/src/core/lib/security/transport/security_connector.c
@@ -137,9 +137,9 @@
                                         grpc_auth_context **auth_context,
                                         grpc_closure *on_peer_checked) {
   if (sc == NULL) {
-    grpc_closure_sched(
-        exec_ctx, on_peer_checked,
-        GRPC_ERROR_CREATE("cannot check peer -- no security connector"));
+    grpc_closure_sched(exec_ctx, on_peer_checked,
+                       GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                           "cannot check peer -- no security connector"));
     tsi_peer_destruct(&peer);
   } else {
     sc->vtable->check_peer(exec_ctx, sc, peer, auth_context, on_peer_checked);
@@ -330,7 +330,8 @@
   grpc_error *error = GRPC_ERROR_NONE;
   *auth_context = NULL;
   if (peer.property_count != 1) {
-    error = GRPC_ERROR_CREATE("Fake peers should only have 1 property.");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Fake peers should only have 1 property.");
     goto end;
   }
   prop_name = peer.properties[0].name;
@@ -339,13 +340,14 @@
     char *msg;
     gpr_asprintf(&msg, "Unexpected property in fake peer: %s.",
                  prop_name == NULL ? "<EMPTY>" : prop_name);
-    error = GRPC_ERROR_CREATE(msg);
+    error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     goto end;
   }
   if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE,
               peer.properties[0].value.length)) {
-    error = GRPC_ERROR_CREATE("Invalid value for cert type property.");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Invalid value for cert type property.");
     goto end;
   }
   *auth_context = grpc_auth_context_create(NULL);
@@ -586,18 +588,19 @@
   const tsi_peer_property *p =
       tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
   if (p == NULL) {
-    return GRPC_ERROR_CREATE(
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
         "Cannot check peer: missing selected ALPN property.");
   }
   if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) {
-    return GRPC_ERROR_CREATE("Cannot check peer: invalid ALPN value.");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Cannot check peer: invalid ALPN value.");
   }
 
   /* Check the peer name if specified. */
   if (peer_name != NULL && !ssl_host_matches_name(peer, peer_name)) {
     char *msg;
     gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name);
-    grpc_error *error = GRPC_ERROR_CREATE(msg);
+    grpc_error *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     return error;
   }
diff --git a/src/core/lib/security/transport/security_handshaker.c b/src/core/lib/security/transport/security_handshaker.c
index 7065d26..2f39327 100644
--- a/src/core/lib/security/transport/security_handshaker.c
+++ b/src/core/lib/security/transport/security_handshaker.c
@@ -120,7 +120,7 @@
   if (error == GRPC_ERROR_NONE) {
     // If we were shut down after the handshake succeeded but before an
     // endpoint callback was invoked, we need to generate our own error.
-    error = GRPC_ERROR_CREATE("Handshaker shutdown");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshaker shutdown");
   }
   const char *msg = grpc_error_string(error);
   gpr_log(GPR_DEBUG, "Security handshake failed: %s", msg);
@@ -156,7 +156,8 @@
       tsi_handshaker_create_frame_protector(h->handshaker, NULL, &protector);
   if (result != TSI_OK) {
     error = grpc_set_tsi_error_result(
-        GRPC_ERROR_CREATE("Frame protector creation failed"), result);
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Frame protector creation failed"),
+        result);
     security_handshake_failed_locked(exec_ctx, h, error);
     goto done;
   }
@@ -191,7 +192,7 @@
   tsi_result result = tsi_handshaker_extract_peer(h->handshaker, &peer);
   if (result != TSI_OK) {
     return grpc_set_tsi_error_result(
-        GRPC_ERROR_CREATE("Peer extraction failed"), result);
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Peer extraction failed"), result);
   }
   grpc_security_connector_check_peer(exec_ctx, h->connector, peer,
                                      &h->auth_context, &h->on_peer_checked);
@@ -215,8 +216,8 @@
     }
   } while (result == TSI_INCOMPLETE_DATA);
   if (result != TSI_OK) {
-    return grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Handshake failed"),
-                                     result);
+    return grpc_set_tsi_error_result(
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake failed"), result);
   }
   // Send data.
   grpc_slice to_send =
@@ -234,8 +235,8 @@
   gpr_mu_lock(&h->mu);
   if (error != GRPC_ERROR_NONE || h->shutdown) {
     security_handshake_failed_locked(
-        exec_ctx, h,
-        GRPC_ERROR_CREATE_REFERENCING("Handshake read failed", &error, 1));
+        exec_ctx, h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                         "Handshake read failed", &error, 1));
     gpr_mu_unlock(&h->mu);
     security_handshaker_unref(exec_ctx, h);
     return;
@@ -270,8 +271,9 @@
   }
   if (result != TSI_OK) {
     security_handshake_failed_locked(
-        exec_ctx, h, grpc_set_tsi_error_result(
-                         GRPC_ERROR_CREATE("Handshake failed"), result));
+        exec_ctx, h,
+        grpc_set_tsi_error_result(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake failed"), result));
     gpr_mu_unlock(&h->mu);
     security_handshaker_unref(exec_ctx, h);
     return;
@@ -314,8 +316,8 @@
   gpr_mu_lock(&h->mu);
   if (error != GRPC_ERROR_NONE || h->shutdown) {
     security_handshake_failed_locked(
-        exec_ctx, h,
-        GRPC_ERROR_CREATE_REFERENCING("Handshake write failed", &error, 1));
+        exec_ctx, h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                         "Handshake write failed", &error, 1));
     gpr_mu_unlock(&h->mu);
     security_handshaker_unref(exec_ctx, h);
     return;
@@ -429,7 +431,8 @@
                                          grpc_closure *on_handshake_done,
                                          grpc_handshaker_args *args) {
   grpc_closure_sched(exec_ctx, on_handshake_done,
-                     GRPC_ERROR_CREATE("Failed to create security handshaker"));
+                     GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                         "Failed to create security handshaker"));
 }
 
 static const grpc_handshaker_vtable fail_handshaker_vtable = {
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c
index c47fe56..3cf0632 100644
--- a/src/core/lib/security/transport/server_auth_filter.c
+++ b/src/core/lib/security/transport/server_auth_filter.c
@@ -144,9 +144,10 @@
       calld->transport_op->send_message = NULL;
     }
     calld->transport_op->send_trailing_metadata = NULL;
-    grpc_closure_sched(&exec_ctx, calld->on_done_recv,
-                       grpc_error_set_int(GRPC_ERROR_CREATE(error_details),
-                                          GRPC_ERROR_INT_GRPC_STATUS, status));
+    grpc_closure_sched(
+        &exec_ctx, calld->on_done_recv,
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_details),
+                           GRPC_ERROR_INT_GRPC_STATUS, status));
   }
 
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/src/core/lib/security/transport/tsi_error.c b/src/core/lib/security/transport/tsi_error.c
index afc1733..eae0a67 100644
--- a/src/core/lib/security/transport/tsi_error.c
+++ b/src/core/lib/security/transport/tsi_error.c
@@ -34,7 +34,9 @@
 #include "src/core/lib/security/transport/tsi_error.h"
 
 grpc_error *grpc_set_tsi_error_result(grpc_error *error, tsi_result result) {
-  return grpc_error_set_int(grpc_error_set_str(error, GRPC_ERROR_STR_TSI_ERROR,
-                                               tsi_result_to_string(result)),
-                            GRPC_ERROR_INT_TSI_CODE, result);
+  return grpc_error_set_int(
+      grpc_error_set_str(
+          error, GRPC_ERROR_STR_TSI_ERROR,
+          grpc_slice_from_static_string(tsi_result_to_string(result))),
+      GRPC_ERROR_INT_TSI_CODE, result);
 }
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index 2c5d8c0..895a8a3 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -264,7 +264,7 @@
 static void add_init_error(grpc_error **composite, grpc_error *new) {
   if (new == GRPC_ERROR_NONE) return;
   if (*composite == GRPC_ERROR_NONE)
-    *composite = GRPC_ERROR_CREATE("Call creation failed");
+    *composite = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Call creation failed");
   *composite = grpc_error_add_child(*composite, new);
 }
 
@@ -335,17 +335,17 @@
      * call. */
     if (args->propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) {
       if (0 == (args->propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT)) {
-        add_init_error(&error,
-                       GRPC_ERROR_CREATE("Census tracing propagation requested "
-                                         "without Census context propagation"));
+        add_init_error(&error, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                   "Census tracing propagation requested "
+                                   "without Census context propagation"));
       }
       grpc_call_context_set(
           call, GRPC_CONTEXT_TRACING,
           args->parent_call->context[GRPC_CONTEXT_TRACING].value, NULL);
     } else if (args->propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT) {
-      add_init_error(&error,
-                     GRPC_ERROR_CREATE("Census context propagation requested "
-                                       "without Census tracing propagation"));
+      add_init_error(&error, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                 "Census context propagation requested "
+                                 "without Census tracing propagation"));
     }
     if (args->propagation_mask & GRPC_PROPAGATE_CANCELLATION) {
       call->cancellation_is_inherited = 1;
@@ -603,8 +603,9 @@
 static grpc_error *error_from_status(grpc_status_code status,
                                      const char *description) {
   return grpc_error_set_int(
-      grpc_error_set_str(GRPC_ERROR_CREATE(description),
-                         GRPC_ERROR_STR_GRPC_MESSAGE, description),
+      grpc_error_set_str(GRPC_ERROR_CREATE_FROM_COPIED_STRING(description),
+                         GRPC_ERROR_STR_GRPC_MESSAGE,
+                         grpc_slice_from_copied_string(description)),
       GRPC_ERROR_INT_GRPC_STATUS, status);
 }
 
@@ -624,16 +625,15 @@
     void (*set_value)(grpc_status_code code, void *user_data),
     void *set_value_user_data, grpc_slice *details) {
   grpc_status_code code;
-  const char *msg = NULL;
-  grpc_error_get_status(error, call->send_deadline, &code, &msg, NULL);
+  grpc_slice slice;
+  grpc_error_get_status(error, call->send_deadline, &code, &slice, NULL);
   if (code == GRPC_STATUS_OK && !allow_ok_status) {
     return false;
   }
 
   set_value(code, set_value_user_data);
   if (details != NULL) {
-    *details =
-        msg == NULL ? grpc_empty_slice() : grpc_slice_from_copied_string(msg);
+    *details = grpc_slice_ref_internal(slice);
   }
   return true;
 }
@@ -896,18 +896,19 @@
     grpc_error *error =
         status_code == GRPC_STATUS_OK
             ? GRPC_ERROR_NONE
-            : grpc_error_set_int(GRPC_ERROR_CREATE("Error received from peer"),
+            : grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                     "Error received from peer"),
                                  GRPC_ERROR_INT_GRPC_STATUS,
                                  (intptr_t)status_code);
 
     if (b->idx.named.grpc_message != NULL) {
-      char *msg =
-          grpc_slice_to_c_string(GRPC_MDVALUE(b->idx.named.grpc_message->md));
-      error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, msg);
-      gpr_free(msg);
+      error = grpc_error_set_str(
+          error, GRPC_ERROR_STR_GRPC_MESSAGE,
+          grpc_slice_ref_internal(GRPC_MDVALUE(b->idx.named.grpc_message->md)));
       grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.grpc_message);
     } else if (error != GRPC_ERROR_NONE) {
-      error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "");
+      error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
+                                 grpc_empty_slice());
     }
 
     set_status_from_error(exec_ctx, call, STATUS_FROM_WIRE, error);
@@ -1056,8 +1057,8 @@
     bctl->errors[0] = NULL;
     return e;
   } else {
-    grpc_error *error =
-        GRPC_ERROR_CREATE_REFERENCING("Call batch failed", bctl->errors, n);
+    grpc_error *error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+        "Call batch failed", bctl->errors, n);
     for (size_t i = 0; i < n; i++) {
       GRPC_ERROR_UNREF(bctl->errors[i]);
       bctl->errors[i] = NULL;
@@ -1521,7 +1522,8 @@
         {
           grpc_error *override_error = GRPC_ERROR_NONE;
           if (op->data.send_status_from_server.status != GRPC_STATUS_OK) {
-            override_error = GRPC_ERROR_CREATE("Error from server send status");
+            override_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                "Error from server send status");
           }
           if (op->data.send_status_from_server.status_details != NULL) {
             call->send_extra_metadata[1].md = grpc_mdelem_from_slices(
@@ -1531,8 +1533,9 @@
             call->send_extra_metadata_count++;
             char *msg = grpc_slice_to_c_string(
                 GRPC_MDVALUE(call->send_extra_metadata[1].md));
-            override_error = grpc_error_set_str(
-                override_error, GRPC_ERROR_STR_GRPC_MESSAGE, msg);
+            override_error =
+                grpc_error_set_str(override_error, GRPC_ERROR_STR_GRPC_MESSAGE,
+                                   grpc_slice_from_copied_string(msg));
             gpr_free(msg);
           }
           set_status_from_error(exec_ctx, call, STATUS_FROM_API_OVERRIDE,
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index 16208a5..d6c7aee 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -389,7 +389,8 @@
   grpc_channel_element *elem;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   GRPC_API_TRACE("grpc_channel_destroy(channel=%p)", 1, (channel));
-  op->disconnect_with_error = GRPC_ERROR_CREATE("Channel Destroyed");
+  op->disconnect_with_error =
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel Destroyed");
   elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CHANNEL(channel), 0);
   elem->filter->start_transport_op(&exec_ctx, elem, op);
 
diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c
index 9ddb88b..0c408aa 100644
--- a/src/core/lib/surface/lame_client.c
+++ b/src/core/lib/surface/lame_client.c
@@ -90,7 +90,8 @@
     fill_metadata(exec_ctx, elem, op->recv_trailing_metadata);
   }
   grpc_transport_stream_op_finish_with_failure(
-      exec_ctx, op, GRPC_ERROR_CREATE("lame client channel"));
+      exec_ctx, op,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("lame client channel"));
 }
 
 static char *lame_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
@@ -111,8 +112,9 @@
                        GRPC_ERROR_NONE);
   }
   if (op->send_ping != NULL) {
-    grpc_closure_sched(exec_ctx, op->send_ping,
-                       GRPC_ERROR_CREATE("lame client channel"));
+    grpc_closure_sched(
+        exec_ctx, op->send_ping,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("lame client channel"));
   }
   GRPC_ERROR_UNREF(op->disconnect_with_error);
   if (op->on_consumed != NULL) {
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index 1186a4a..a123c9c 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -288,10 +288,10 @@
   grpc_channel_element *elem;
 
   op->goaway_error =
-      send_goaway
-          ? grpc_error_set_int(GRPC_ERROR_CREATE("Server shutdown"),
-                               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK)
-          : GRPC_ERROR_NONE;
+      send_goaway ? grpc_error_set_int(
+                        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server shutdown"),
+                        GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK)
+                  : GRPC_ERROR_NONE;
   op->set_accept_stream = true;
   sc->slice = grpc_slice_from_copied_string("Server shutdown");
   op->disconnect_with_error = send_disconnect;
@@ -712,8 +712,9 @@
     return;
   }
 
-  kill_pending_work_locked(exec_ctx, server,
-                           GRPC_ERROR_CREATE("Server Shutdown"));
+  kill_pending_work_locked(
+      exec_ctx, server,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server Shutdown"));
 
   if (server->root_channel_data.next != &server->root_channel_data ||
       server->listeners_destroyed < num_listeners(server)) {
@@ -771,8 +772,8 @@
     /* do nothing */
   } else {
     grpc_error *src_error = error;
-    error =
-        GRPC_ERROR_CREATE_REFERENCING("Missing :authority or :path", &error, 1);
+    error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+        "Missing :authority or :path", &error, 1);
     GRPC_ERROR_UNREF(src_error);
   }
 
@@ -1219,7 +1220,8 @@
   op->on_connectivity_state_change = &chand->channel_connectivity_changed;
   op->connectivity_state = &chand->connectivity_state;
   if (gpr_atm_acq_load(&s->shutdown_flag) != 0) {
-    op->disconnect_with_error = GRPC_ERROR_CREATE("Server shutdown");
+    op->disconnect_with_error =
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server shutdown");
   }
   grpc_transport_perform_op(exec_ctx, transport, op);
 }
@@ -1277,8 +1279,9 @@
 
   /* collect all unregistered then registered calls */
   gpr_mu_lock(&server->mu_call);
-  kill_pending_work_locked(&exec_ctx, server,
-                           GRPC_ERROR_CREATE("Server Shutdown"));
+  kill_pending_work_locked(
+      &exec_ctx, server,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server Shutdown"));
   gpr_mu_unlock(&server->mu_call);
 
   maybe_finish_shutdown(&exec_ctx, server);
@@ -1308,8 +1311,9 @@
   channel_broadcaster_init(server, &broadcaster);
   gpr_mu_unlock(&server->mu_global);
 
-  channel_broadcaster_shutdown(&exec_ctx, &broadcaster, false /* send_goaway */,
-                               GRPC_ERROR_CREATE("Cancelling all calls"));
+  channel_broadcaster_shutdown(
+      &exec_ctx, &broadcaster, false /* send_goaway */,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Cancelling all calls"));
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -1357,16 +1361,16 @@
   int request_id;
   if (gpr_atm_acq_load(&server->shutdown_flag)) {
     fail_call(exec_ctx, server, cq_idx, rc,
-              GRPC_ERROR_CREATE("Server Shutdown"));
+              GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server Shutdown"));
     return GRPC_CALL_OK;
   }
   request_id = gpr_stack_lockfree_pop(server->request_freelist_per_cq[cq_idx]);
   if (request_id == -1) {
     /* out of request ids: just fail this one */
     fail_call(exec_ctx, server, cq_idx, rc,
-              grpc_error_set_int(GRPC_ERROR_CREATE("Out of request ids"),
-                                 GRPC_ERROR_INT_LIMIT,
-                                 server->max_requested_calls_per_cq));
+              grpc_error_set_int(
+                  GRPC_ERROR_CREATE_FROM_STATIC_STRING("Out of request ids"),
+                  GRPC_ERROR_INT_LIMIT, server->max_requested_calls_per_cq));
     return GRPC_CALL_OK;
   }
   switch (rc->type) {
diff --git a/src/core/lib/surface/validate_metadata.c b/src/core/lib/surface/validate_metadata.c
index 7ec9137..6e76c4e 100644
--- a/src/core/lib/surface/validate_metadata.c
+++ b/src/core/lib/surface/validate_metadata.c
@@ -39,6 +39,7 @@
 #include <grpc/support/port_platform.h>
 
 #include "src/core/lib/iomgr/error.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 
 static grpc_error *conforms_to(grpc_slice slice, const uint8_t *legal_bits,
@@ -52,9 +53,10 @@
     if ((legal_bits[byte] & (1 << bit)) == 0) {
       char *dump = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
       grpc_error *error = grpc_error_set_str(
-          grpc_error_set_int(GRPC_ERROR_CREATE(err_desc), GRPC_ERROR_INT_OFFSET,
+          grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(err_desc),
+                             GRPC_ERROR_INT_OFFSET,
                              p - GRPC_SLICE_START_PTR(slice)),
-          GRPC_ERROR_STR_RAW_BYTES, dump);
+          GRPC_ERROR_STR_RAW_BYTES, grpc_slice_from_copied_string(dump));
       gpr_free(dump);
       return error;
     }
@@ -74,10 +76,12 @@
       0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
   if (GRPC_SLICE_LENGTH(slice) == 0) {
-    return GRPC_ERROR_CREATE("Metadata keys cannot be zero length");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Metadata keys cannot be zero length");
   }
   if (GRPC_SLICE_START_PTR(slice)[0] == ':') {
-    return GRPC_ERROR_CREATE("Metadata keys cannot start with :");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Metadata keys cannot start with :");
   }
   return conforms_to(slice, legal_header_bits, "Illegal header key");
 }
diff --git a/src/core/lib/transport/connectivity_state.c b/src/core/lib/transport/connectivity_state.c
index afe1f61..3757b25 100644
--- a/src/core/lib/transport/connectivity_state.c
+++ b/src/core/lib/transport/connectivity_state.c
@@ -79,7 +79,8 @@
       *w->current = GRPC_CHANNEL_SHUTDOWN;
       error = GRPC_ERROR_NONE;
     } else {
-      error = GRPC_ERROR_CREATE("Shutdown connectivity owner");
+      error =
+          GRPC_ERROR_CREATE_FROM_STATIC_STRING("Shutdown connectivity owner");
     }
     grpc_closure_sched(exec_ctx, w->notify, error);
     gpr_free(w);
diff --git a/src/core/lib/transport/error_utils.c b/src/core/lib/transport/error_utils.c
index ef55e56..4e70f87 100644
--- a/src/core/lib/transport/error_utils.c
+++ b/src/core/lib/transport/error_utils.c
@@ -55,7 +55,7 @@
 }
 
 void grpc_error_get_status(grpc_error *error, gpr_timespec deadline,
-                           grpc_status_code *code, const char **msg,
+                           grpc_status_code *code, grpc_slice *slice,
                            grpc_http2_error_code *http_error) {
   // Start with the parent error and recurse through the tree of children
   // until we find the first one that has a status code.
@@ -97,11 +97,11 @@
 
   // If the error has a status message, use it.  Otherwise, fall back to
   // the error description.
-  if (msg != NULL) {
-    *msg = grpc_error_get_str(found_error, GRPC_ERROR_STR_GRPC_MESSAGE);
-    if (*msg == NULL && error != GRPC_ERROR_NONE) {
-      *msg = grpc_error_get_str(found_error, GRPC_ERROR_STR_DESCRIPTION);
-      if (*msg == NULL) *msg = "unknown error";  // Just in case.
+  if (slice != NULL) {
+    if (!grpc_error_get_str(found_error, GRPC_ERROR_STR_GRPC_MESSAGE, slice)) {
+      if (!grpc_error_get_str(found_error, GRPC_ERROR_STR_DESCRIPTION, slice)) {
+        *slice = grpc_slice_from_static_string("unknown error");
+      }
     }
   }
 
diff --git a/src/core/lib/transport/error_utils.h b/src/core/lib/transport/error_utils.h
index 1053388..3b44466 100644
--- a/src/core/lib/transport/error_utils.h
+++ b/src/core/lib/transport/error_utils.h
@@ -44,7 +44,7 @@
 /// attributes (code, msg, http_status) are unneeded, they can be passed as
 /// NULL.
 void grpc_error_get_status(grpc_error *error, gpr_timespec deadline,
-                           grpc_status_code *code, const char **msg,
+                           grpc_status_code *code, grpc_slice *slice,
                            grpc_http2_error_code *http_status);
 
 /// A utility function to check whether there is a clear status code that
diff --git a/src/core/lib/transport/metadata_batch.c b/src/core/lib/transport/metadata_batch.c
index fc2c52b..fa73244 100644
--- a/src/core/lib/transport/metadata_batch.c
+++ b/src/core/lib/transport/metadata_batch.c
@@ -101,12 +101,10 @@
 }
 
 grpc_error *grpc_attach_md_to_error(grpc_error *src, grpc_mdelem md) {
-  char *k = grpc_slice_to_c_string(GRPC_MDKEY(md));
-  char *v = grpc_slice_to_c_string(GRPC_MDVALUE(md));
   grpc_error *out = grpc_error_set_str(
-      grpc_error_set_str(src, GRPC_ERROR_STR_KEY, k), GRPC_ERROR_STR_VALUE, v);
-  gpr_free(k);
-  gpr_free(v);
+      grpc_error_set_str(src, GRPC_ERROR_STR_KEY,
+                         grpc_slice_ref_internal(GRPC_MDKEY(md))),
+      GRPC_ERROR_STR_VALUE, grpc_slice_ref_internal(GRPC_MDVALUE(md)));
   return out;
 }
 
@@ -126,7 +124,8 @@
     return GRPC_ERROR_NONE;
   }
   return grpc_attach_md_to_error(
-      GRPC_ERROR_CREATE("Unallowed duplicate metadata"), storage->md);
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Unallowed duplicate metadata"),
+      storage->md);
 }
 
 static void maybe_unlink_callout(grpc_metadata_batch *batch,
@@ -302,7 +301,7 @@
                       const char *composite_error_string) {
   if (error == GRPC_ERROR_NONE) return;
   if (*composite == GRPC_ERROR_NONE) {
-    *composite = GRPC_ERROR_CREATE(composite_error_string);
+    *composite = GRPC_ERROR_CREATE_FROM_COPIED_STRING(composite_error_string);
   }
   *composite = grpc_error_add_child(*composite, error);
 }
diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c
index fdedfe2..4870dc1 100644
--- a/test/core/bad_client/bad_client.c
+++ b/test/core/bad_client/bad_client.c
@@ -163,8 +163,9 @@
       gpr_event_wait(&a.done_write, grpc_timeout_seconds_to_deadline(5)));
 
   if (flags & GRPC_BAD_CLIENT_DISCONNECT) {
-    grpc_endpoint_shutdown(&exec_ctx, sfd.client,
-                           GRPC_ERROR_CREATE("Forced Disconnect"));
+    grpc_endpoint_shutdown(
+        &exec_ctx, sfd.client,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Disconnect"));
     grpc_endpoint_destroy(&exec_ctx, sfd.client);
     grpc_exec_ctx_finish(&exec_ctx);
     sfd.client = NULL;
@@ -190,8 +191,9 @@
       grpc_slice_buffer_destroy_internal(&exec_ctx, &args.incoming);
     }
     // Shutdown.
-    grpc_endpoint_shutdown(&exec_ctx, sfd.client,
-                           GRPC_ERROR_CREATE("Test Shutdown"));
+    grpc_endpoint_shutdown(
+        &exec_ctx, sfd.client,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
     grpc_endpoint_destroy(&exec_ctx, sfd.client);
     grpc_exec_ctx_finish(&exec_ctx);
   }
diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
index 187757d..b85ca89 100644
--- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
@@ -55,7 +55,7 @@
   if (g_fail_resolution) {
     g_fail_resolution = false;
     gpr_mu_unlock(&g_mu);
-    return GRPC_ERROR_CREATE("Forced Failure");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
   } else {
     gpr_mu_unlock(&g_mu);
     *addrs = gpr_malloc(sizeof(**addrs));
diff --git a/test/core/end2end/bad_server_response_test.c b/test/core/end2end/bad_server_response_test.c
index 39a98e8..c37a292 100644
--- a/test/core/end2end/bad_server_response_test.c
+++ b/test/core/end2end/bad_server_response_test.c
@@ -303,7 +303,7 @@
 
   /* clean up */
   grpc_endpoint_shutdown(&exec_ctx, state.tcp,
-                         GRPC_ERROR_CREATE("Test Shutdown"));
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
   grpc_endpoint_destroy(&exec_ctx, state.tcp);
   cleanup_rpc(&exec_ctx);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/end2end/fixtures/http_proxy_fixture.c b/test/core/end2end/fixtures/http_proxy_fixture.c
index bcd1c99..451ed26 100644
--- a/test/core/end2end/fixtures/http_proxy_fixture.c
+++ b/test/core/end2end/fixtures/http_proxy_fixture.c
@@ -342,7 +342,7 @@
     char* msg;
     gpr_asprintf(&msg, "HTTP proxy got request method %s",
                  conn->http_request.method);
-    error = GRPC_ERROR_CREATE(msg);
+    error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
     gpr_free(msg);
     proxy_connection_failed(exec_ctx, conn, true /* is_client */,
                             "HTTP proxy read request", error);
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index 0de8b94..9cc3f56 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -390,9 +390,9 @@
     *r->addrs = addrs;
     grpc_closure_sched(exec_ctx, r->on_done, GRPC_ERROR_NONE);
   } else {
-    grpc_closure_sched(
-        exec_ctx, r->on_done,
-        GRPC_ERROR_CREATE_REFERENCING("Resolution failed", &error, 1));
+    grpc_closure_sched(exec_ctx, r->on_done,
+                       GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                           "Resolution failed", &error, 1));
   }
 
   gpr_free(r->addr);
@@ -461,8 +461,8 @@
                           grpc_endpoint **ep, gpr_timespec deadline) {
   if (gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) < 0) {
     *ep = NULL;
-    grpc_closure_sched(exec_ctx, closure,
-                       GRPC_ERROR_CREATE("Connect deadline exceeded"));
+    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                              "Connect deadline exceeded"));
     return;
   }
 
diff --git a/test/core/end2end/goaway_server_test.c b/test/core/end2end/goaway_server_test.c
index a9634bf..4bb258e 100644
--- a/test/core/end2end/goaway_server_test.c
+++ b/test/core/end2end/goaway_server_test.c
@@ -71,7 +71,7 @@
   gpr_mu_lock(&g_mu);
   if (g_resolve_port < 0) {
     gpr_mu_unlock(&g_mu);
-    return GRPC_ERROR_CREATE("Forced Failure");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
   } else {
     *addrs = gpr_malloc(sizeof(**addrs));
     (*addrs)->naddrs = 1;
diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c
index 65216cf..ebfe3b0 100644
--- a/test/core/end2end/tests/filter_call_init_fails.c
+++ b/test/core/end2end/tests/filter_call_init_fails.c
@@ -206,9 +206,9 @@
 static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
                                   grpc_call_element *elem,
                                   const grpc_call_element_args *args) {
-  return grpc_error_set_int(GRPC_ERROR_CREATE("access denied"),
-                            GRPC_ERROR_INT_GRPC_STATUS,
-                            GRPC_STATUS_PERMISSION_DENIED);
+  return grpc_error_set_int(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("access denied"),
+      GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_PERMISSION_DENIED);
 }
 
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c
index c968f30..e6b02ea 100644
--- a/test/core/end2end/tests/filter_causes_close.c
+++ b/test/core/end2end/tests/filter_causes_close.c
@@ -210,7 +210,7 @@
   call_data *calld = elem->call_data;
   grpc_closure_sched(
       exec_ctx, calld->recv_im_ready,
-      grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING(
+      grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
                              "Failure that's not preventable.", &error, 1),
                          GRPC_ERROR_INT_GRPC_STATUS,
                          GRPC_STATUS_PERMISSION_DENIED));
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 94067a8..e274796 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -233,11 +233,13 @@
 
   if (shutdown) {
     gpr_log(GPR_DEBUG, "shutdown read");
-    grpc_endpoint_shutdown(&exec_ctx, state.read_ep,
-                           GRPC_ERROR_CREATE("Test Shutdown"));
+    grpc_endpoint_shutdown(
+        &exec_ctx, state.read_ep,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
     gpr_log(GPR_DEBUG, "shutdown write");
-    grpc_endpoint_shutdown(&exec_ctx, state.write_ep,
-                           GRPC_ERROR_CREATE("Test Shutdown"));
+    grpc_endpoint_shutdown(
+        &exec_ctx, state.write_ep,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
   }
   grpc_exec_ctx_flush(&exec_ctx);
 
@@ -299,7 +301,7 @@
                                          grpc_schedule_on_exec_ctx));
   wait_for_fail_count(&exec_ctx, &fail_count, 0);
   grpc_endpoint_shutdown(&exec_ctx, f.client_ep,
-                         GRPC_ERROR_CREATE("Test Shutdown"));
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
   wait_for_fail_count(&exec_ctx, &fail_count, 1);
   grpc_endpoint_read(&exec_ctx, f.client_ep, &slice_buffer,
                      grpc_closure_create(inc_on_failure, &fail_count,
@@ -311,7 +313,7 @@
                                           grpc_schedule_on_exec_ctx));
   wait_for_fail_count(&exec_ctx, &fail_count, 3);
   grpc_endpoint_shutdown(&exec_ctx, f.client_ep,
-                         GRPC_ERROR_CREATE("Test Shutdown"));
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
   wait_for_fail_count(&exec_ctx, &fail_count, 3);
 
   grpc_slice_buffer_destroy_internal(&exec_ctx, &slice_buffer);
diff --git a/test/core/iomgr/error_test.c b/test/core/iomgr/error_test.c
index 2a6b1b1..5c60a4d 100644
--- a/test/core/iomgr/error_test.c
+++ b/test/core/iomgr/error_test.c
@@ -44,7 +44,7 @@
 #include "test/core/util/test_config.h"
 
 static void test_set_get_int() {
-  grpc_error* error = GRPC_ERROR_CREATE("Test");
+  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test");
   GPR_ASSERT(error);
   intptr_t i = 0;
   GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_FILE_LINE, &i));
@@ -66,26 +66,27 @@
 }
 
 static void test_set_get_str() {
-  grpc_error* error = GRPC_ERROR_CREATE("Test");
+  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test");
 
-  GPR_ASSERT(!grpc_error_get_str(error, GRPC_ERROR_STR_SYSCALL));
-  GPR_ASSERT(!grpc_error_get_str(error, GRPC_ERROR_STR_TSI_ERROR));
+  grpc_slice str;
+  GPR_ASSERT(!grpc_error_get_str(error, GRPC_ERROR_STR_SYSCALL, &str));
+  GPR_ASSERT(!grpc_error_get_str(error, GRPC_ERROR_STR_TSI_ERROR, &str));
 
-  const char* c = grpc_error_get_str(error, GRPC_ERROR_STR_FILE);
-  GPR_ASSERT(c);
-  GPR_ASSERT(strstr(c, "error_test.c"));  // __FILE__ expands differently on
-                                          // Windows. All should at least
-                                          // contain error_test.c
+  GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_FILE, &str));
+  GPR_ASSERT(strstr((char*)GRPC_SLICE_START_PTR(str),
+                    "error_test.c"));  // __FILE__ expands differently on
+                                       // Windows. All should at least
+                                       // contain error_test.c
 
-  c = grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION);
-  GPR_ASSERT(c);
-  GPR_ASSERT(!strcmp(c, "Test"));
+  GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION, &str));
+  GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "Test",
+                      GRPC_SLICE_LENGTH(str)));
 
-  error =
-      grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "longer message");
-  c = grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE);
-  GPR_ASSERT(c);
-  GPR_ASSERT(!strcmp(c, "longer message"));
+  error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
+                             grpc_slice_from_static_string("longer message"));
+  GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, &str));
+  GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "longer message",
+                      GRPC_SLICE_LENGTH(str)));
 
   GRPC_ERROR_UNREF(error);
 }
@@ -93,26 +94,28 @@
 static void test_copy_and_unref() {
   // error1 has one ref
   grpc_error* error1 = grpc_error_set_str(
-      GRPC_ERROR_CREATE("Test"), GRPC_ERROR_STR_GRPC_MESSAGE, "message");
-  const char* c = grpc_error_get_str(error1, GRPC_ERROR_STR_GRPC_MESSAGE);
-  GPR_ASSERT(c);
-  GPR_ASSERT(!strcmp(c, "message"));
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test"), GRPC_ERROR_STR_GRPC_MESSAGE,
+      grpc_slice_from_static_string("message"));
+  grpc_slice str;
+  GPR_ASSERT(grpc_error_get_str(error1, GRPC_ERROR_STR_GRPC_MESSAGE, &str));
+  GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "message",
+                      GRPC_SLICE_LENGTH(str)));
 
   // error 1 has two refs
   GRPC_ERROR_REF(error1);
   // this gives error3 a ref to the new error, and decrements error1 to one ref
-  grpc_error* error3 =
-      grpc_error_set_str(error1, GRPC_ERROR_STR_SYSCALL, "syscall");
+  grpc_error* error3 = grpc_error_set_str(
+      error1, GRPC_ERROR_STR_SYSCALL, grpc_slice_from_static_string("syscall"));
   GPR_ASSERT(error3 != error1);  // should not be the same because of extra ref
-  c = grpc_error_get_str(error3, GRPC_ERROR_STR_GRPC_MESSAGE);
-  GPR_ASSERT(c);
-  GPR_ASSERT(!strcmp(c, "message"));
+  GPR_ASSERT(grpc_error_get_str(error3, GRPC_ERROR_STR_GRPC_MESSAGE, &str));
+  GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "message",
+                      GRPC_SLICE_LENGTH(str)));
 
   // error 1 should not have a syscall but 3 should
-  GPR_ASSERT(!grpc_error_get_str(error1, GRPC_ERROR_STR_SYSCALL));
-  c = grpc_error_get_str(error3, GRPC_ERROR_STR_SYSCALL);
-  GPR_ASSERT(c);
-  GPR_ASSERT(!strcmp(c, "syscall"));
+  GPR_ASSERT(!grpc_error_get_str(error1, GRPC_ERROR_STR_SYSCALL, &str));
+  GPR_ASSERT(grpc_error_get_str(error3, GRPC_ERROR_STR_SYSCALL, &str));
+  GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), "syscall",
+                      GRPC_SLICE_LENGTH(str)));
 
   GRPC_ERROR_UNREF(error1);
   GRPC_ERROR_UNREF(error3);
@@ -120,8 +123,10 @@
 
 static void test_create_referencing() {
   grpc_error* child = grpc_error_set_str(
-      GRPC_ERROR_CREATE("Child"), GRPC_ERROR_STR_GRPC_MESSAGE, "message");
-  grpc_error* parent = GRPC_ERROR_CREATE_REFERENCING("Parent", &child, 1);
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child"),
+      GRPC_ERROR_STR_GRPC_MESSAGE, grpc_slice_from_static_string("message"));
+  grpc_error* parent =
+      GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Parent", &child, 1);
   GPR_ASSERT(parent);
 
   GRPC_ERROR_UNREF(child);
@@ -130,14 +135,18 @@
 
 static void test_create_referencing_many() {
   grpc_error* children[3];
-  children[0] = grpc_error_set_str(GRPC_ERROR_CREATE("Child1"),
-                                   GRPC_ERROR_STR_GRPC_MESSAGE, "message");
-  children[1] = grpc_error_set_int(GRPC_ERROR_CREATE("Child2"),
-                                   GRPC_ERROR_INT_HTTP2_ERROR, 5);
-  children[2] = grpc_error_set_str(GRPC_ERROR_CREATE("Child3"),
-                                   GRPC_ERROR_STR_GRPC_MESSAGE, "message 3");
+  children[0] = grpc_error_set_str(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child1"),
+      GRPC_ERROR_STR_GRPC_MESSAGE, grpc_slice_from_static_string("message"));
+  children[1] =
+      grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child2"),
+                         GRPC_ERROR_INT_HTTP2_ERROR, 5);
+  children[2] = grpc_error_set_str(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child3"),
+      GRPC_ERROR_STR_GRPC_MESSAGE, grpc_slice_from_static_string("message 3"));
 
-  grpc_error* parent = GRPC_ERROR_CREATE_REFERENCING("Parent", children, 3);
+  grpc_error* parent =
+      GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Parent", children, 3);
   GPR_ASSERT(parent);
 
   for (size_t i = 0; i < 3; ++i) {
@@ -148,10 +157,11 @@
 
 static void print_error_string() {
   grpc_error* error =
-      grpc_error_set_int(GRPC_ERROR_CREATE("Error"), GRPC_ERROR_INT_GRPC_STATUS,
-                         GRPC_STATUS_UNIMPLEMENTED);
+      grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"),
+                         GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNIMPLEMENTED);
   error = grpc_error_set_int(error, GRPC_ERROR_INT_SIZE, 666);
-  error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "message");
+  error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
+                             grpc_slice_from_static_string("message"));
   // gpr_log(GPR_DEBUG, "%s", grpc_error_string(error));
   GRPC_ERROR_UNREF(error);
 }
@@ -159,15 +169,18 @@
 static void print_error_string_reference() {
   grpc_error* children[2];
   children[0] = grpc_error_set_str(
-      grpc_error_set_int(GRPC_ERROR_CREATE("1"), GRPC_ERROR_INT_GRPC_STATUS,
-                         GRPC_STATUS_UNIMPLEMENTED),
-      GRPC_ERROR_STR_GRPC_MESSAGE, "message for child 1");
+      grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("1"),
+                         GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNIMPLEMENTED),
+      GRPC_ERROR_STR_GRPC_MESSAGE,
+      grpc_slice_from_static_string("message for child 1"));
   children[1] = grpc_error_set_str(
-      grpc_error_set_int(GRPC_ERROR_CREATE("2sd"), GRPC_ERROR_INT_GRPC_STATUS,
-                         GRPC_STATUS_INTERNAL),
-      GRPC_ERROR_STR_GRPC_MESSAGE, "message for child 2");
+      grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("2sd"),
+                         GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL),
+      GRPC_ERROR_STR_GRPC_MESSAGE,
+      grpc_slice_from_static_string("message for child 2"));
 
-  grpc_error* parent = GRPC_ERROR_CREATE_REFERENCING("Parent", children, 2);
+  grpc_error* parent =
+      GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Parent", children, 2);
 
   gpr_log(GPR_DEBUG, "%s", grpc_error_string(parent));
 
@@ -186,15 +199,17 @@
   GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i));
   GPR_ASSERT(i == fake_errno);
 
-  const char* c = grpc_error_get_str(error, GRPC_ERROR_STR_SYSCALL);
-  GPR_ASSERT(c);
-  GPR_ASSERT(!strcmp(c, syscall));
+  grpc_slice str;
+  GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_SYSCALL, &str));
+  GPR_ASSERT(!strncmp((char*)GRPC_SLICE_START_PTR(str), syscall,
+                      GRPC_SLICE_LENGTH(str)));
   GRPC_ERROR_UNREF(error);
 }
 
 static void test_special() {
   grpc_error* error = GRPC_ERROR_NONE;
-  error = grpc_error_add_child(error, GRPC_ERROR_CREATE("test child"));
+  error = grpc_error_add_child(
+      error, GRPC_ERROR_CREATE_FROM_STATIC_STRING("test child"));
   intptr_t i;
   GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &i));
   GPR_ASSERT(i == GRPC_STATUS_OK);
diff --git a/test/core/iomgr/ev_epoll_linux_test.c b/test/core/iomgr/ev_epoll_linux_test.c
index 4ec9599..d69f9a9 100644
--- a/test/core/iomgr/ev_epoll_linux_test.c
+++ b/test/core/iomgr/ev_epoll_linux_test.c
@@ -90,7 +90,7 @@
 
   for (i = 0; i < num_fds; i++) {
     grpc_fd_shutdown(exec_ctx, tfds[i].fd,
-                     GRPC_ERROR_CREATE("test_fd_cleanup"));
+                     GRPC_ERROR_CREATE_FROM_STATIC_STRING("test_fd_cleanup"));
     grpc_exec_ctx_flush(exec_ctx);
 
     grpc_fd_orphan(exec_ctx, tfds[i].fd, NULL, &release_fd, "test_fd_cleanup");
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index c1a0ef5..81d2692 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -133,7 +133,7 @@
   gpr_free(se);
   /* Start to shutdown listen fd. */
   grpc_fd_shutdown(exec_ctx, sv->em_fd,
-                   GRPC_ERROR_CREATE("session_shutdown_cb"));
+                   GRPC_ERROR_CREATE_FROM_STATIC_STRING("session_shutdown_cb"));
 }
 
 /* Called when data become readable in a session. */
diff --git a/test/core/iomgr/pollset_set_test.c b/test/core/iomgr/pollset_set_test.c
index f27e9db..3a9d459 100644
--- a/test/core/iomgr/pollset_set_test.c
+++ b/test/core/iomgr/pollset_set_test.c
@@ -143,7 +143,8 @@
   int release_fd;
 
   for (int i = 0; i < num_fds; i++) {
-    grpc_fd_shutdown(exec_ctx, tfds[i].fd, GRPC_ERROR_CREATE("fd cleanup"));
+    grpc_fd_shutdown(exec_ctx, tfds[i].fd,
+                     GRPC_ERROR_CREATE_FROM_STATIC_STRING("fd cleanup"));
     grpc_exec_ctx_flush(exec_ctx);
 
     /* grpc_fd_orphan frees the memory allocated for grpc_fd. Normally it also
diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c
index b324b5a..2fae677 100644
--- a/test/core/iomgr/tcp_client_posix_test.c
+++ b/test/core/iomgr/tcp_client_posix_test.c
@@ -77,8 +77,9 @@
                          grpc_error *error) {
   GPR_ASSERT(g_connecting != NULL);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
-  grpc_endpoint_shutdown(exec_ctx, g_connecting,
-                         GRPC_ERROR_CREATE("must_succeed called"));
+  grpc_endpoint_shutdown(
+      exec_ctx, g_connecting,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("must_succeed called"));
   grpc_endpoint_destroy(exec_ctx, g_connecting);
   g_connecting = NULL;
   finish_connection();
diff --git a/test/core/iomgr/tcp_client_uv_test.c b/test/core/iomgr/tcp_client_uv_test.c
index 064119f..92fc393 100644
--- a/test/core/iomgr/tcp_client_uv_test.c
+++ b/test/core/iomgr/tcp_client_uv_test.c
@@ -73,8 +73,9 @@
                          grpc_error *error) {
   GPR_ASSERT(g_connecting != NULL);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
-  grpc_endpoint_shutdown(exec_ctx, g_connecting,
-                         GRPC_ERROR_CREATE("must_succeed called"));
+  grpc_endpoint_shutdown(
+      exec_ctx, g_connecting,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("must_succeed called"));
   grpc_endpoint_destroy(exec_ctx, g_connecting);
   g_connecting = NULL;
   finish_connection();
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index 6e51432..112743b 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -163,7 +163,8 @@
 static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
                        grpc_pollset *pollset,
                        grpc_tcp_server_acceptor *acceptor) {
-  grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_CREATE("Connected"));
+  grpc_endpoint_shutdown(exec_ctx, tcp,
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connected"));
   grpc_endpoint_destroy(exec_ctx, tcp);
 
   on_connect_result temp_result;
@@ -285,7 +286,7 @@
   if (g_nconnects != nconnects_before + 1) {
     gpr_mu_unlock(g_mu);
     close(clifd);
-    return GRPC_ERROR_CREATE("Didn't connect");
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Didn't connect");
   }
   close(clifd);
   *result = g_result;
diff --git a/test/core/iomgr/tcp_server_uv_test.c b/test/core/iomgr/tcp_server_uv_test.c
index 0fc7459..1e03958 100644
--- a/test/core/iomgr/tcp_server_uv_test.c
+++ b/test/core/iomgr/tcp_server_uv_test.c
@@ -115,7 +115,8 @@
 static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
                        grpc_pollset *pollset,
                        grpc_tcp_server_acceptor *acceptor) {
-  grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_CREATE("Connected"));
+  grpc_endpoint_shutdown(exec_ctx, tcp,
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connected"));
   grpc_endpoint_destroy(exec_ctx, tcp);
 
   on_connect_result temp_result;
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index d2b76ba..b3775e9 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -166,10 +166,12 @@
   GPR_ASSERT(incoming.count == 1);
   GPR_ASSERT(grpc_slice_eq(s, incoming.slices[0]));
 
-  grpc_endpoint_shutdown(&exec_ctx, f.client_ep,
-                         GRPC_ERROR_CREATE("test_leftover end"));
-  grpc_endpoint_shutdown(&exec_ctx, f.server_ep,
-                         GRPC_ERROR_CREATE("test_leftover end"));
+  grpc_endpoint_shutdown(
+      &exec_ctx, f.client_ep,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("test_leftover end"));
+  grpc_endpoint_shutdown(
+      &exec_ctx, f.server_ep,
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("test_leftover end"));
   grpc_endpoint_destroy(&exec_ctx, f.client_ep);
   grpc_endpoint_destroy(&exec_ctx, f.server_ep);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/security/ssl_server_fuzzer.c b/test/core/security/ssl_server_fuzzer.c
index 7a3612c..cbbaf9f 100644
--- a/test/core/security/ssl_server_fuzzer.c
+++ b/test/core/security/ssl_server_fuzzer.c
@@ -115,8 +115,9 @@
   // server will wait for more data. Explicitly fail the server by shutting down
   // the endpoint.
   if (!state.done_callback_called) {
-    grpc_endpoint_shutdown(&exec_ctx, mock_endpoint,
-                           GRPC_ERROR_CREATE("Explicit close"));
+    grpc_endpoint_shutdown(
+        &exec_ctx, mock_endpoint,
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Explicit close"));
     grpc_exec_ctx_flush(&exec_ctx);
   }
 
diff --git a/test/core/surface/concurrent_connectivity_test.c b/test/core/surface/concurrent_connectivity_test.c
index ff92738..2f7c3df 100644
--- a/test/core/surface/concurrent_connectivity_test.c
+++ b/test/core/surface/concurrent_connectivity_test.c
@@ -109,7 +109,8 @@
                        grpc_tcp_server_acceptor *acceptor) {
   gpr_free(acceptor);
   struct server_thread_args *args = (struct server_thread_args *)vargs;
-  grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_CREATE("Connected"));
+  grpc_endpoint_shutdown(exec_ctx, tcp,
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connected"));
   grpc_endpoint_destroy(exec_ctx, tcp);
   GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, NULL));
 }
diff --git a/test/core/util/mock_endpoint.c b/test/core/util/mock_endpoint.c
index b8fed7e..c747297 100644
--- a/test/core/util/mock_endpoint.c
+++ b/test/core/util/mock_endpoint.c
@@ -89,8 +89,9 @@
   grpc_mock_endpoint *m = (grpc_mock_endpoint *)ep;
   gpr_mu_lock(&m->mu);
   if (m->on_read) {
-    grpc_closure_sched(exec_ctx, m->on_read, GRPC_ERROR_CREATE_REFERENCING(
-                                                 "Endpoint Shutdown", &why, 1));
+    grpc_closure_sched(exec_ctx, m->on_read,
+                       GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                           "Endpoint Shutdown", &why, 1));
     m->on_read = NULL;
   }
   gpr_mu_unlock(&m->mu);
diff --git a/test/core/util/passthru_endpoint.c b/test/core/util/passthru_endpoint.c
index 5f27f9a..121567f 100644
--- a/test/core/util/passthru_endpoint.c
+++ b/test/core/util/passthru_endpoint.c
@@ -75,7 +75,8 @@
   half *m = (half *)ep;
   gpr_mu_lock(&m->parent->mu);
   if (m->parent->shutdown) {
-    grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_CREATE("Already shutdown"));
+    grpc_closure_sched(
+        exec_ctx, cb, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Already shutdown"));
   } else if (m->read_buffer.count > 0) {
     grpc_slice_buffer_swap(&m->read_buffer, slices);
     grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_NONE);
@@ -98,7 +99,7 @@
   grpc_error *error = GRPC_ERROR_NONE;
   m->parent->stats->num_writes++;
   if (m->parent->shutdown) {
-    error = GRPC_ERROR_CREATE("Endpoint already shutdown");
+    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Endpoint already shutdown");
   } else if (m->on_read != NULL) {
     for (size_t i = 0; i < slices->count; i++) {
       grpc_slice_buffer_add(m->on_read_out, grpc_slice_ref(slices->slices[i]));
@@ -126,14 +127,16 @@
   gpr_mu_lock(&m->parent->mu);
   m->parent->shutdown = true;
   if (m->on_read) {
-    grpc_closure_sched(exec_ctx, m->on_read,
-                       GRPC_ERROR_CREATE_REFERENCING("Shutdown", &why, 1));
+    grpc_closure_sched(
+        exec_ctx, m->on_read,
+        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Shutdown", &why, 1));
     m->on_read = NULL;
   }
   m = other_half(m);
   if (m->on_read) {
-    grpc_closure_sched(exec_ctx, m->on_read,
-                       GRPC_ERROR_CREATE_REFERENCING("Shutdown", &why, 1));
+    grpc_closure_sched(
+        exec_ctx, m->on_read,
+        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Shutdown", &why, 1));
     m->on_read = NULL;
   }
   gpr_mu_unlock(&m->parent->mu);
diff --git a/test/core/util/reconnect_server.c b/test/core/util/reconnect_server.c
index 7fbd0ca..90af1c1 100644
--- a/test/core/util/reconnect_server.c
+++ b/test/core/util/reconnect_server.c
@@ -80,7 +80,8 @@
   gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
   timestamp_list *new_tail;
   peer = grpc_endpoint_get_peer(tcp);
-  grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_CREATE("Connected"));
+  grpc_endpoint_shutdown(exec_ctx, tcp,
+                         GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connected"));
   grpc_endpoint_destroy(exec_ctx, tcp);
   if (peer) {
     last_colon = strrchr(peer, ':');
diff --git a/test/cpp/microbenchmarks/bm_error.cc b/test/cpp/microbenchmarks/bm_error.cc
index c4f6aa1..00e1a08 100644
--- a/test/cpp/microbenchmarks/bm_error.cc
+++ b/test/cpp/microbenchmarks/bm_error.cc
@@ -51,21 +51,30 @@
 };
 typedef std::unique_ptr<grpc_error, ErrorDeleter> ErrorPtr;
 
-static void BM_ErrorCreate(benchmark::State& state) {
+static void BM_ErrorCreateFromStatic(benchmark::State& state) {
   TrackCounters track_counters;
   while (state.KeepRunning()) {
-    GRPC_ERROR_UNREF(GRPC_ERROR_CREATE("Error"));
+    GRPC_ERROR_UNREF(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"));
   }
   track_counters.Finish(state);
 }
-BENCHMARK(BM_ErrorCreate);
+BENCHMARK(BM_ErrorCreateFromStatic);
+
+static void BM_ErrorCreateFromCopied(benchmark::State& state) {
+  TrackCounters track_counters;
+  while (state.KeepRunning()) {
+    GRPC_ERROR_UNREF(GRPC_ERROR_CREATE_FROM_COPIED_STRING("Error not inline"));
+  }
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_ErrorCreateFromCopied);
 
 static void BM_ErrorCreateAndSetStatus(benchmark::State& state) {
   TrackCounters track_counters;
   while (state.KeepRunning()) {
-    GRPC_ERROR_UNREF(grpc_error_set_int(GRPC_ERROR_CREATE("Error"),
-                                        GRPC_ERROR_INT_GRPC_STATUS,
-                                        GRPC_STATUS_ABORTED));
+    GRPC_ERROR_UNREF(
+        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"),
+                           GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_ABORTED));
   }
   track_counters.Finish(state);
 }
@@ -75,9 +84,10 @@
   TrackCounters track_counters;
   while (state.KeepRunning()) {
     GRPC_ERROR_UNREF(grpc_error_set_str(
-        grpc_error_set_int(GRPC_ERROR_CREATE("GOAWAY received"),
-                           GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)0),
-        GRPC_ERROR_STR_RAW_BYTES, "raw bytes"));
+        grpc_error_set_int(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("GOAWAY received"),
+            GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)0),
+        GRPC_ERROR_STR_RAW_BYTES, grpc_slice_from_static_string("raw bytes")));
   }
   track_counters.Finish(state);
 }
@@ -85,7 +95,7 @@
 
 static void BM_ErrorCreateAndSetIntLoop(benchmark::State& state) {
   TrackCounters track_counters;
-  grpc_error* error = GRPC_ERROR_CREATE("Error");
+  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error");
   int n = 0;
   while (state.KeepRunning()) {
     error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, n++);
@@ -97,10 +107,11 @@
 
 static void BM_ErrorCreateAndSetStrLoop(benchmark::State& state) {
   TrackCounters track_counters;
-  grpc_error* error = GRPC_ERROR_CREATE("Error");
+  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error");
   const char* str = "hello";
   while (state.KeepRunning()) {
-    error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, str);
+    error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
+                               grpc_slice_from_static_string(str));
   }
   GRPC_ERROR_UNREF(error);
   track_counters.Finish(state);
@@ -109,7 +120,7 @@
 
 static void BM_ErrorRefUnref(benchmark::State& state) {
   TrackCounters track_counters;
-  grpc_error* error = GRPC_ERROR_CREATE("Error");
+  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error");
   while (state.KeepRunning()) {
     GRPC_ERROR_UNREF(GRPC_ERROR_REF(error));
   }
@@ -138,8 +149,8 @@
 
 static void BM_ErrorGetMissingInt(benchmark::State& state) {
   TrackCounters track_counters;
-  ErrorPtr error(
-      grpc_error_set_int(GRPC_ERROR_CREATE("Error"), GRPC_ERROR_INT_INDEX, 1));
+  ErrorPtr error(grpc_error_set_int(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_INDEX, 1));
   while (state.KeepRunning()) {
     intptr_t value;
     grpc_error_get_int(error.get(), GRPC_ERROR_INT_OFFSET, &value);
@@ -150,8 +161,8 @@
 
 static void BM_ErrorGetPresentInt(benchmark::State& state) {
   TrackCounters track_counters;
-  ErrorPtr error(
-      grpc_error_set_int(GRPC_ERROR_CREATE("Error"), GRPC_ERROR_INT_OFFSET, 1));
+  ErrorPtr error(grpc_error_set_int(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_OFFSET, 1));
   while (state.KeepRunning()) {
     intptr_t value;
     grpc_error_get_int(error.get(), GRPC_ERROR_INT_OFFSET, &value);
@@ -186,7 +197,7 @@
 
  private:
   const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
-  ErrorPtr error_{GRPC_ERROR_CREATE("Error")};
+  ErrorPtr error_{GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error")};
 };
 
 class ErrorWithGrpcStatus {
@@ -196,9 +207,9 @@
 
  private:
   const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
-  ErrorPtr error_{grpc_error_set_int(GRPC_ERROR_CREATE("Error"),
-                                     GRPC_ERROR_INT_GRPC_STATUS,
-                                     GRPC_STATUS_UNIMPLEMENTED)};
+  ErrorPtr error_{grpc_error_set_int(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_GRPC_STATUS,
+      GRPC_STATUS_UNIMPLEMENTED)};
 };
 
 class ErrorWithHttpError {
@@ -208,9 +219,9 @@
 
  private:
   const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
-  ErrorPtr error_{grpc_error_set_int(GRPC_ERROR_CREATE("Error"),
-                                     GRPC_ERROR_INT_HTTP2_ERROR,
-                                     GRPC_HTTP2_COMPRESSION_ERROR)};
+  ErrorPtr error_{grpc_error_set_int(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_HTTP2_ERROR,
+      GRPC_HTTP2_COMPRESSION_ERROR)};
 };
 
 class ErrorWithNestedGrpcStatus {
@@ -220,11 +231,12 @@
 
  private:
   const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
-  ErrorPtr nested_error_{grpc_error_set_int(GRPC_ERROR_CREATE("Error"),
-                                            GRPC_ERROR_INT_GRPC_STATUS,
-                                            GRPC_STATUS_UNIMPLEMENTED)};
+  ErrorPtr nested_error_{grpc_error_set_int(
+      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_GRPC_STATUS,
+      GRPC_STATUS_UNIMPLEMENTED)};
   grpc_error* nested_errors_[1] = {nested_error_.get()};
-  ErrorPtr error_{GRPC_ERROR_CREATE_REFERENCING("Error", nested_errors_, 1)};
+  ErrorPtr error_{GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+      "Error", nested_errors_, 1)};
 };
 
 template <class Fixture>
@@ -253,8 +265,8 @@
   Fixture fixture;
   while (state.KeepRunning()) {
     grpc_status_code status;
-    const char* msg;
-    grpc_error_get_status(fixture.error(), fixture.deadline(), &status, &msg,
+    grpc_slice slice;
+    grpc_error_get_status(fixture.error(), fixture.deadline(), &status, &slice,
                           NULL);
   }
   track_counters.Finish(state);