diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index f0fa85a77bb082dfcd10204b5589b02161d3f122..57bf2fad5abb62348c4c99b82934516fac3e68a1 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -93,7 +93,7 @@ typedef struct {
 } grpc_arg;
 
 /** An array of arguments that can be passed around.
-    
+
     Used to set optional channel-level configuration.
     These configuration options are modelled as key-value pairs as defined
     by grpc_arg; keys are strings to allow easy backwards-compatible extension
@@ -174,6 +174,9 @@ typedef struct grpc_byte_buffer_reader grpc_byte_buffer_reader;
 void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
                                   grpc_byte_buffer *buffer);
 
+/** Cleanup and destroy \a reader */
+void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader);
+
 /* At the end of the stream, returns 0. Otherwise, returns 1 and sets slice to
    be the returned slice. Caller is responsible for calling gpr_slice_unref on
    the result. */
diff --git a/src/core/surface/byte_buffer_reader.c b/src/core/surface/byte_buffer_reader.c
index 5d97609aaad04722cb6c36e997652827c2d71caf..41ad7002748d4eb435a7e29e0268468a3e65db9f 100644
--- a/src/core/surface/byte_buffer_reader.c
+++ b/src/core/surface/byte_buffer_reader.c
@@ -48,6 +48,11 @@ void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
   }
 }
 
+void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader) {
+  /* no-op: the user is responsible for memory deallocation.
+   * Other cleanup operations would go here if needed. */
+}
+
 int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader,
                                  gpr_slice *slice) {
   grpc_byte_buffer *buffer = reader->buffer;