diff --git a/src/coeio.c b/src/coeio.c
index f1a4dabe3d7c440af77e89eeb993e88b69c697f4..936baf0cc175e3eb485933ad4acf9fcd5d658b51 100644
--- a/src/coeio.c
+++ b/src/coeio.c
@@ -39,7 +39,6 @@
 #include <sys/socket.h>
 
 #include "fiber.h"
-#include "diag.h"
 #include "third_party/tarantool_ev.h"
 
 /*
@@ -156,6 +155,8 @@ coio_on_exec(eio_req *req)
 {
 	struct coio_task *task = (struct coio_task *) req;
 	req->result = task->task_cb(task);
+	if (req->result)
+		diag_move(diag_get(), &task->diag);
 }
 
 /**
@@ -218,6 +219,7 @@ coio_task(struct coio_task *task, coio_task_cb func,
 	task->task_cb = func;
 	task->timeout_cb = on_timeout;
 	task->complete = 0;
+	diag_create(&task->diag);
 
 	eio_submit(&task->base);
 	fiber_yield_timeout(timeout);
@@ -230,7 +232,10 @@ coio_task(struct coio_task *task, coio_task_cb func,
 			diag_set(TimedOut);
 		return -1;
 	}
-	diag_clear(&fiber()->diag);
+	if (task->base.result) {
+		diag_move(&task->diag, &fiber()->diag);
+		return -1;
+	}
 	return 0;
 }
 
@@ -239,6 +244,8 @@ coio_on_call(eio_req *req)
 {
 	struct coio_task *task = (struct coio_task *) req;
 	req->result = task->call_cb(task->ap);
+	if (req->result)
+		diag_move(diag_get(), &task->diag);
 }
 
 ssize_t
@@ -257,6 +264,7 @@ coio_call(ssize_t (*func)(va_list ap), ...)
 	task->fiber = fiber();
 	task->call_cb = func;
 	task->complete = 0;
+	diag_create(&task->diag);
 
 	bool cancellable = fiber_set_cancellable(false);
 
@@ -273,6 +281,8 @@ coio_call(ssize_t (*func)(va_list ap), ...)
 
 	ssize_t result = task->base.result;
 	int save_errno = errno;
+	if (result)
+		diag_move(&task->diag, diag_get());
 	free(task);
 	errno = save_errno;
 	return result;
diff --git a/src/coeio.h b/src/coeio.h
index f572120cb0cb7a326d0de12299ee871dc9965d78..8f1807f22d183a7bd8ab63c6039a1af549106b45 100644
--- a/src/coeio.h
+++ b/src/coeio.h
@@ -37,6 +37,7 @@
 #include <stdarg.h>
 
 #include "third_party/tarantool_eio.h"
+#include "diag.h"
 
 #if defined(__cplusplus)
 extern "C" {
@@ -77,6 +78,8 @@ struct coio_task {
 	};
 	/** Callback results. */
 	int complete;
+	/** Task diag **/
+	struct diag diag;
 };
 
 ssize_t