diff --git a/src/box/iproto.cc b/src/box/iproto.cc
index 5b7ea88379827b38861e311605cd97990a135277..3ec7aacb27014aa44ca9da04852a3ed7669ccb50 100644
--- a/src/box/iproto.cc
+++ b/src/box/iproto.cc
@@ -3395,6 +3395,13 @@ struct iproto_cfg_msg: public cbus_call_msg
 			/** Whether the request handler is set or reset. */
 			bool is_set;
 		} override;
+		struct {
+			/**
+			 * Connection that executing iproto_drop_connections.
+			 * NULL if the function is called not from connection.
+			 */
+			struct iproto_connection *owner;
+		} drop_connections;
 	};
 	struct iproto_thread *iproto_thread;
 };
@@ -3495,8 +3502,14 @@ iproto_do_cfg_f(struct cbus_call_msg *m)
 			if (!con->is_in_replication &&
 			    con->state == IPROTO_CONNECTION_ALIVE)
 				iproto_connection_close(con);
-			con->is_drop_pending = true;
-			iproto_thread->drop_pending_connection_count++;
+			/*
+			 * Do not wait deletion of connection that called
+			 * iproto_drop_connections to avoid deadlock.
+			 */
+			if (con != cfg_msg->drop_connections.owner) {
+				con->is_drop_pending = true;
+				iproto_thread->drop_pending_connection_count++;
+			}
 			if (con->state != IPROTO_CONNECTION_DESTROYED) {
 				cmsg_init(&con->cancel_msg, cancel_route);
 				cpipe_push(&iproto_thread->tx_pipe,
@@ -3575,11 +3588,16 @@ iproto_drop_connections(void)
 {
 	static struct latch latch = LATCH_INITIALIZER(latch);
 	latch_lock(&latch);
+	struct iproto_connection *owner = NULL;
+	struct session *session = fiber_get_session(fiber());
+	if (session != NULL && session->type == SESSION_TYPE_BINARY)
+		owner = (struct iproto_connection *)session->meta.connection;
 	drop_pending_thread_count = iproto_threads_count;
 	for (int i = 0; i < iproto_threads_count; i++) {
 		struct iproto_cfg_msg *cfg_msg =
 			(struct iproto_cfg_msg *)xmalloc(sizeof(*cfg_msg));
 		iproto_cfg_msg_create(cfg_msg, IPROTO_CFG_DROP_CONNECTIONS);
+		cfg_msg->drop_connections.owner = owner;
 		iproto_do_cfg_async(&iproto_threads[i], cfg_msg);
 	}