diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 6e6ca7cd53cdab6f96d7b5cf4f9df20228b7c96f..17109de587ba2eff709cfc8e3a7b40ecdd9923fc 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -329,7 +329,7 @@ namespace Grpc.Core.Internal
 
         protected override Exception GetRpcExceptionClientOnly()
         {
-            return new RpcException(finishedStatus.Value.Status);
+            return new RpcException(finishedStatus.Value.Status, finishedStatus.Value.Trailers);
         }
 
         protected override Task CheckSendAllowedOrEarlyResult()
@@ -348,7 +348,7 @@ namespace Grpc.Core.Internal
                 // Writing after the call has finished is not a programming error because server can close
                 // the call anytime, so don't throw directly, but let the write task finish with an error.
                 var tcs = new TaskCompletionSource<object>();
-                tcs.SetException(new RpcException(finishedStatus.Value.Status));
+                tcs.SetException(new RpcException(finishedStatus.Value.Status, finishedStatus.Value.Trailers));
                 return tcs.Task;
             }
 
@@ -468,7 +468,7 @@ namespace Grpc.Core.Internal
             var status = receivedStatus.Status;
             if (status.StatusCode != StatusCode.OK)
             {
-                unaryResponseTcs.SetException(new RpcException(status));
+                unaryResponseTcs.SetException(new RpcException(status, receivedStatus.Trailers));
                 return;
             }
 
@@ -506,7 +506,7 @@ namespace Grpc.Core.Internal
             var status = receivedStatus.Status;
             if (status.StatusCode != StatusCode.OK)
             {
-                streamingResponseCallFinishedTcs.SetException(new RpcException(status));
+                streamingResponseCallFinishedTcs.SetException(new RpcException(status, receivedStatus.Trailers));
                 return;
             }
 
diff --git a/src/csharp/Grpc.Core/RpcException.cs b/src/csharp/Grpc.Core/RpcException.cs
index 01b9e4fb1a14bad8df66d818a97e1fe589ecd67f..d2c912e73af42936139e7924092e8dceb8211a17 100644
--- a/src/csharp/Grpc.Core/RpcException.cs
+++ b/src/csharp/Grpc.Core/RpcException.cs
@@ -17,6 +17,7 @@
 #endregion
 
 using System;
+using Grpc.Core.Utils;
 
 namespace Grpc.Core
 {
@@ -26,6 +27,7 @@ namespace Grpc.Core
     public class RpcException : Exception
     {
         private readonly Status status;
+        private readonly Metadata trailers;
 
         /// <summary>
         /// Creates a new <c>RpcException</c> associated with given status.
@@ -34,6 +36,7 @@ namespace Grpc.Core
         public RpcException(Status status) : base(status.ToString())
         {
             this.status = status;
+            this.trailers = Metadata.Empty;
         }
 
         /// <summary>
@@ -44,6 +47,18 @@ namespace Grpc.Core
         public RpcException(Status status, string message) : base(message)
         {
             this.status = status;
+            this.trailers = Metadata.Empty;
+        }
+
+        /// <summary>
+        /// Creates a new <c>RpcException</c> associated with given status and trailing response metadata.
+        /// </summary>
+        /// <param name="status">Resulting status of a call.</param>
+        /// <param name="trailers">Response trailing metadata.</param> 
+        public RpcException(Status status, Metadata trailers) : base(status.ToString())
+        {
+            this.status = status;
+            this.trailers = GrpcPreconditions.CheckNotNull(trailers);
         }
 
         /// <summary>
@@ -56,5 +71,18 @@ namespace Grpc.Core
                 return status;
             }
         }
+
+        /// <summary>
+        /// Gets the call trailing metadata.
+        /// Trailers only have meaningful content for client-side calls (in which case they represent the trailing metadata sent by the server when closing the call).
+        /// Instances of <c>RpcException</c> thrown by the server-side part of the stack will have trailers always set to empty.
+        /// </summary>
+        public Metadata Trailers
+        {
+            get
+            {
+                return trailers;
+            }
+        }
     }
 }