diff --git a/src/core/iomgr/udp_server.c b/src/core/iomgr/udp_server.c
index 1304f2067ea53133d6aaebb4d422a96ff83e82e4..9903e970e6643d1286be825c71d77d0cc50a2ee8 100644
--- a/src/core/iomgr/udp_server.c
+++ b/src/core/iomgr/udp_server.c
@@ -278,7 +278,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, int success) {
 
   /* Tell the registered callback that data is available to read. */
   GPR_ASSERT(sp->read_cb);
-  sp->read_cb(sp->emfd, sp->server->grpc_server);
+  sp->read_cb(exec_ctx, sp->emfd, sp->server->grpc_server);
 
   /* Re-arm the notification event so we get another chance to read. */
   grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
diff --git a/src/core/iomgr/udp_server.h b/src/core/iomgr/udp_server.h
index dbbe09710932d615875ee77f53dca2b357222291..de5736c426221ff5a7e909f29fb857b3cc2525a4 100644
--- a/src/core/iomgr/udp_server.h
+++ b/src/core/iomgr/udp_server.h
@@ -43,7 +43,8 @@ typedef struct grpc_server grpc_server;
 typedef struct grpc_udp_server grpc_udp_server;
 
 /* Called when data is available to read from the socket. */
-typedef void (*grpc_udp_server_read_cb)(grpc_fd *emfd, grpc_server *server);
+typedef void (*grpc_udp_server_read_cb)(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
+                                        grpc_server *server);
 
 /* Create a server, initially not bound to any ports */
 grpc_udp_server *grpc_udp_server_create(void);
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index fc0026da4df9a5b2ebf43650ef686de6460fe02e..86e8767937825dcd16e4606091a117446b9b3dd8 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -49,7 +49,8 @@ static grpc_pollset g_pollset;
 static int g_number_of_reads = 0;
 static int g_number_of_bytes_read = 0;
 
-static void on_read(grpc_fd *emfd, grpc_server *server) {
+static void on_read(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
+                    grpc_server *server) {
   char read_buffer[512];
   ssize_t byte_count;