diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c
index 81f673f856efde5c1f2ec63c106a0f68131b49e5..688a586e1899d738634f0967eb0551bc6f265e2c 100644
--- a/src/core/surface/channel.c
+++ b/src/core/surface/channel.c
@@ -229,7 +229,9 @@ static void destroy_channel(void *p, int ok) {
     registered_call *rc = channel->registered_calls;
     channel->registered_calls = rc->next;
     GRPC_MDELEM_UNREF(rc->path);
-    GRPC_MDELEM_UNREF(rc->authority);
+    if (rc->authority) {
+      GRPC_MDELEM_UNREF(rc->authority);
+    }
     gpr_free(rc);
   }
   grpc_mdctx_unref(channel->metadata_context);
diff --git a/src/cpp/client/channel.cc b/src/cpp/client/channel.cc
index 5df81e641ef9079167b0c23f33b15e5f9db2567c..ee143d68a0f8d931b790866ac2ff68d5f49251ee 100644
--- a/src/cpp/client/channel.cc
+++ b/src/cpp/client/channel.cc
@@ -51,13 +51,16 @@
 
 namespace grpc {
 
-Channel::Channel(const grpc::string& target, grpc_channel* channel)
-    : target_(target), c_channel_(channel) {}
+Channel::Channel(grpc_channel* channel) : c_channel_(channel) {}
+
+Channel::Channel(const grpc::string& host, grpc_channel* channel)
+    : host_(host), c_channel_(channel) {}
 
 Channel::~Channel() { grpc_channel_destroy(c_channel_); }
 
 Call Channel::CreateCall(const RpcMethod& method, ClientContext* context,
                          CompletionQueue* cq) {
+  const char* host_str = host_.empty() ? NULL : host_.c_str();
   auto c_call =
       method.channel_tag() && context->authority().empty()
           ? grpc_channel_create_registered_call(c_channel_, cq->cq(),
@@ -65,7 +68,7 @@ Call Channel::CreateCall(const RpcMethod& method, ClientContext* context,
                                                 context->raw_deadline())
           : grpc_channel_create_call(c_channel_, cq->cq(), method.name(),
                                      context->authority().empty()
-                                         ? target_.c_str()
+                                         ? host_str
                                          : context->authority().c_str(),
                                      context->raw_deadline());
   grpc_census_call_set_context(c_call, context->census_context());
@@ -86,7 +89,8 @@ void Channel::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) {
 }
 
 void* Channel::RegisterMethod(const char* method) {
-  return grpc_channel_register_call(c_channel_, method, target_.c_str());
+  return grpc_channel_register_call(c_channel_, method,
+                                    host_.empty() ? NULL : host_.c_str());
 }
 
 }  // namespace grpc
diff --git a/src/cpp/client/channel.h b/src/cpp/client/channel.h
index 9108713c589473f73196b56b0b1152c9e597396c..8660146856cc951e0c056d69b637bbb4b5058bc0 100644
--- a/src/cpp/client/channel.h
+++ b/src/cpp/client/channel.h
@@ -52,7 +52,8 @@ class StreamContextInterface;
 
 class Channel GRPC_FINAL : public GrpcLibrary, public ChannelInterface {
  public:
-  Channel(const grpc::string& target, grpc_channel* c_channel);
+  explicit Channel(grpc_channel* c_channel);
+  Channel(const grpc::string& host, grpc_channel* c_channel);
   ~Channel() GRPC_OVERRIDE;
 
   virtual void* RegisterMethod(const char* method) GRPC_OVERRIDE;
@@ -62,7 +63,7 @@ class Channel GRPC_FINAL : public GrpcLibrary, public ChannelInterface {
                                 Call* call) GRPC_OVERRIDE;
 
  private:
-  const grpc::string target_;
+  const grpc::string host_;
   grpc_channel* const c_channel_;  // owned
 };
 
diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc
index dbe2694a78d1336a63538305a23ccb9455daea11..21d01b739d6c373dbfea7470679f6ee2826c744e 100644
--- a/src/cpp/client/create_channel.cc
+++ b/src/cpp/client/create_channel.cc
@@ -51,7 +51,7 @@ std::shared_ptr<ChannelInterface> CreateChannel(
   cp_args.SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING,
                     user_agent_prefix.str());
   return creds ? creds->CreateChannel(target, cp_args)
-               : std::shared_ptr<ChannelInterface>(new Channel(
-                     target, grpc_lame_client_channel_create(NULL)));
+               : std::shared_ptr<ChannelInterface>(
+                     new Channel(grpc_lame_client_channel_create(NULL)));
 }
 }  // namespace grpc
diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc
index e802fa8034e3ff5fa9f4a7a7939dfe70e30f1695..d8dcaa1436a632836e2b6fd65bf7bd7d9816fe90 100644
--- a/src/cpp/client/insecure_credentials.cc
+++ b/src/cpp/client/insecure_credentials.cc
@@ -49,7 +49,7 @@ class InsecureCredentialsImpl GRPC_FINAL : public Credentials {
     grpc_channel_args channel_args;
     args.SetChannelArgs(&channel_args);
     return std::shared_ptr<ChannelInterface>(new Channel(
-        target, grpc_insecure_channel_create(target.c_str(), &channel_args)));
+        grpc_insecure_channel_create(target.c_str(), &channel_args)));
   }
 
   // InsecureCredentials should not be applied to a call.
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index abf0cb387e317b363a7ba3b5a43ab2f286c7b8fd..2d6114e06b815d993e4ac6009f136281abd5cc17 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -44,8 +44,7 @@ std::shared_ptr<grpc::ChannelInterface> SecureCredentials::CreateChannel(
   grpc_channel_args channel_args;
   args.SetChannelArgs(&channel_args);
   return std::shared_ptr<ChannelInterface>(new Channel(
-      args.GetSslTargetNameOverride().empty() ? target
-                                              : args.GetSslTargetNameOverride(),
+      args.GetSslTargetNameOverride(),
       grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args)));
 }
 
diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc
index 4951c82b9aa82458a5990cadc701610013847c8b..b53c32144b1cf9060586540b119ac2fa1d368c57 100644
--- a/test/cpp/end2end/generic_end2end_test.cc
+++ b/test/cpp/end2end/generic_end2end_test.cc
@@ -100,11 +100,11 @@ std::unique_ptr<ByteBuffer> SerializeToByteBuffer(
 
 class GenericEnd2endTest : public ::testing::Test {
  protected:
-  GenericEnd2endTest() : generic_service_("*") {}
+  GenericEnd2endTest() : generic_service_("*"), server_host_("localhost") {}
 
   void SetUp() GRPC_OVERRIDE {
     int port = grpc_pick_unused_port_or_die();
-    server_address_ << "localhost:" << port;
+    server_address_ << server_host_ << ":" << port;
     // Setup server
     ServerBuilder builder;
     builder.AddListeningPort(server_address_.str(), InsecureServerCredentials());
@@ -165,7 +165,7 @@ class GenericEnd2endTest : public ::testing::Test {
                                    srv_cq_.get(), tag(4));
 
       verify_ok(srv_cq_.get(), 4, true);
-      EXPECT_EQ(server_address_.str(), srv_ctx.host());
+      EXPECT_EQ(server_host_, srv_ctx.host());
       EXPECT_EQ(kMethodName, srv_ctx.method());
       ByteBuffer recv_buffer;
       stream.Read(&recv_buffer, tag(5));
@@ -200,6 +200,7 @@ class GenericEnd2endTest : public ::testing::Test {
   std::unique_ptr<grpc::GenericStub> generic_stub_;
   std::unique_ptr<Server> server_;
   AsyncGenericService generic_service_;
+  const grpc::string server_host_;
   std::ostringstream server_address_;
 };
 
@@ -237,7 +238,7 @@ TEST_F(GenericEnd2endTest, SimpleBidiStreaming) {
                                srv_cq_.get(), tag(2));
 
   verify_ok(srv_cq_.get(), 2, true);
-  EXPECT_EQ(server_address_.str(), srv_ctx.host());
+  EXPECT_EQ(server_host_, srv_ctx.host());
   EXPECT_EQ(kMethodName, srv_ctx.method());
 
   std::unique_ptr<ByteBuffer> send_buffer =