diff --git a/src/box/engine_sophia.cc b/src/box/engine_sophia.cc
index a8c158dfbca82810f2bcf8bb7aafead9bc898f06..5489202748522a555627548f13878a070c31da5b 100644
--- a/src/box/engine_sophia.cc
+++ b/src/box/engine_sophia.cc
@@ -252,6 +252,7 @@ SophiaFactory::begin(struct txn *txn, struct space *space)
 	if (txn->n_stmts == 1) {
 		assert(tx == NULL);
 		SophiaIndex *index = (SophiaIndex *)index_find(space, 0);
+		(void) index;
 		assert(index->db != NULL);
 		tx = sp_begin(env);
 		if (tx == NULL)
diff --git a/src/box/error.cc b/src/box/error.cc
index 5b92e59b0424ae214a9be546e05aef45cf2a3f24..8f9bde98775ff00a043a70f2b73e73979686829b 100644
--- a/src/box/error.cc
+++ b/src/box/error.cc
@@ -54,8 +54,7 @@ ClientError::ClientError(const char *file, unsigned line, const char *msg,
 void
 ClientError::log() const
 {
-	_say(S_ERROR, m_file, m_line, NULL, "%s: %s", tnt_errcode_str(m_errcode),
-	     m_errmsg);
+	_say(S_ERROR, m_file, m_line, m_errmsg, "%s", tnt_errcode_str(m_errcode));
 }
 
 
diff --git a/src/box/recovery.cc b/src/box/recovery.cc
index 619f4b6e212b18e0cc89746b632b731df416019c..2b38313271ccd9c4e8dd96f5146ed41ab43541c6 100644
--- a/src/box/recovery.cc
+++ b/src/box/recovery.cc
@@ -341,10 +341,12 @@ recover_xlog(struct recovery_state *r, struct xlog *l)
 		try {
 			recovery_process(r, &row);
 		} catch (SystemError *e) {
-			say_error("can't apply row: %s", e->errmsg());
+			say_error("can't apply row: ");
+			e->log();
 			goto end;
 		} catch (Exception *e) {
-			say_error("can't apply row: %s", e->errmsg());
+			say_error("can't apply row: ");
+			e->log();
 			if (l->dir->panic_if_error)
 				goto end;
 		}
diff --git a/src/box/replica.cc b/src/box/replica.cc
index 1b2819086d270d334545d457bf32b9d7d85e989d..7c17abf141ef743bad9a4eb8e9b7331e46e3b56a 100644
--- a/src/box/replica.cc
+++ b/src/box/replica.cc
@@ -220,20 +220,23 @@ pull_from_remote(va_list ap)
 {
 	struct recovery_state *r = va_arg(ap, struct recovery_state *);
 	struct ev_io coio;
-	struct iobuf *iobuf = NULL;
+	struct iobuf *iobuf = iobuf_new(fiber_name(fiber()));
 	ev_loop *loop = loop();
 
 	coio_init(&coio);
 
-	for (;;) {
+	auto coio_guard = make_scoped_guard([&] {
+		iobuf_delete(iobuf);
+		evio_close(loop(), &coio);
+	});
+
+	while (true) {
 		const char *err = NULL;
 		try {
 			struct xrow_header row;
 			fiber_setcancellable(true);
 			if (! evio_is_active(&coio)) {
 				remote_set_status(&r->remote, "connecting");
-				if (iobuf == NULL)
-					iobuf = iobuf_new(fiber_name(fiber()));
 				err = "can't connect to master";
 				remote_connect(r, &coio, iobuf);
 				/* Send SUBSCRIBE request */
@@ -245,24 +248,31 @@ pull_from_remote(va_list ap)
 				remote_set_status(&r->remote, "connected");
 			}
 			err = "can't read row";
+			/**
+			 * If there is an error in subscribe, it's
+			 * sent directly in response to subscribe.
+			 * If subscribe is successful, there is no
+			 * "OK" response, but a stream of rows.
+			 * from the binary log.
+			 */
 			remote_read_row(&coio, iobuf, &row);
-			if (!iproto_type_is_dml(row.type))
-				xrow_decode_error(&row);  /* error */
 			fiber_setcancellable(false);
 			err = NULL;
-
 			r->remote.recovery_lag = ev_now(loop) - row.tm;
 			r->remote.recovery_last_update_tstamp =
 				ev_now(loop);
 
+			if (iproto_type_is_error(row.type))
+				xrow_decode_error(&row);  /* error */
 			recovery_process(r, &row);
 
 			iobuf_reset(iobuf);
 			fiber_gc();
+		} catch (ClientError *e) {
+			remote_set_status(&r->remote, "stopped");
+			throw;
 		} catch (FiberCancelException *e) {
 			remote_set_status(&r->remote, "failed");
-			iobuf_delete(iobuf);
-			evio_close(loop, &coio);
 			throw;
 		} catch (Exception *e) {
 			remote_set_status(&r->remote, "failed");
@@ -308,11 +318,7 @@ recovery_follow_remote(struct recovery_state *r)
 	say_crit("starting replication from %s", uri);
 	snprintf(name, sizeof(name), "replica/%s", uri);
 
-	try {
-		f = fiber_new(name, pull_from_remote);
-	} catch (Exception *e) {
-		return;
-	}
+	f = fiber_new(name, pull_from_remote);
 
 	r->remote.reader = f;
 	fiber_call(f, r);
diff --git a/src/box/xrow.cc b/src/box/xrow.cc
index aedc8d19d3d9e91799703beb3041ec0753c4819e..b446a7bc8426be3a66bf060fc4254acd150f224e 100644
--- a/src/box/xrow.cc
+++ b/src/box/xrow.cc
@@ -161,8 +161,7 @@ xrow_encode_uuid(char *pos, const struct tt_uuid *in)
 }
 
 int
-xrow_to_iovec(const struct xrow_header *row,
-	      struct iovec *out)
+xrow_to_iovec(const struct xrow_header *row, struct iovec *out)
 {
 	static const int iov0_len = mp_sizeof_uint(UINT32_MAX);
 	int iovcnt = xrow_header_encode(row, out + 1) + 1;
diff --git a/src/say.cc b/src/say.cc
index 3d213f6f361c6523516e582f0817ac165b5fcd32..ec96fddcf17b78bb3a1714cd5c116f27d15cb343 100644
--- a/src/say.cc
+++ b/src/say.cc
@@ -281,7 +281,7 @@ vsay(int level, const char *filename, int line, const char *error, const char *f
 		}
 	}
 
-	if (level == S_WARN || level == S_ERROR)
+	if (level == S_WARN || level == S_ERROR || level == S_SYSERROR)
 		p += snprintf(buf + p, len - p, " %s:%i", filename, line);
 
 	p += snprintf(buf + p, len - p, " %c> ", level_to_char(level));
diff --git a/src/sio.cc b/src/sio.cc
index dc04c4eaea1b3ca8417caedc96b8363742f34ef1..3fbdde6171b67f5e46ce76414bd092e78b8ae343 100644
--- a/src/sio.cc
+++ b/src/sio.cc
@@ -304,7 +304,7 @@ sio_writev_all(int fd, struct iovec *iov, int iovcnt)
 {
 	ssize_t bytes_total = 0;
 	struct iovec *iovend = iov + iovcnt;
-	while(1) {
+	while (1) {
 		int cnt = iovend - iov;
 		if (cnt > IOV_MAX)
 			cnt = IOV_MAX;
@@ -315,8 +315,16 @@ sio_writev_all(int fd, struct iovec *iov, int iovcnt)
 			tnt_raise(SocketError, fd, "writev(%d)", cnt);
 		}
 		bytes_total += bytes_written;
-		while (bytes_written >= iov->iov_len)
+		/*
+		 * Check for iov < iovend, since otherwise
+		 * if iovend->iov_len is 0, iov may go beyond
+		 * iovend
+		 */
+		while (bytes_written >= iov->iov_len) {
 			bytes_written -= (iov++)->iov_len;
+			if (iov == iovend)
+				break;
+		}
 		if (iov == iovend)
 			break;
 		iov->iov_base = (char *) iov->iov_base + bytes_written;