diff --git a/src/box/errcode.h b/src/box/errcode.h
index 1a6015a32414f275d69563ed8b9670a5e1812b26..1b00926f9f1417b457712e5fc48f33e187909706 100644
--- a/src/box/errcode.h
+++ b/src/box/errcode.h
@@ -323,7 +323,7 @@ struct errcode_record {
 	/*268 */_(ER_ILLEGAL_OPTIONS,		"Illegal options: %s")   \
 	/*269 */_(ER_ILLEGAL_OPTIONS_FORMAT,    "Each option in third argument must be a table containing only one key value pair")   \
 	/*270 */_(ER_CANT_GENERATE,		"Can't generate %s") \
-	/*271 */_(ER_UNUSED5,			"") \
+	/*271 */_(ER_SQL_STATEMENT_BUSY,	"SQL statement %d is busy") \
 	/*272 */_(ER_SCHEMA_UPGRADE_IN_PROGRESS, "Schema upgrade is already in progress") \
 	/*273 */_(ER_UNUSED7,			"") \
 	/*274 */_(ER_UNCONFIGURED,		"Please call box.cfg{} first") \
diff --git a/src/box/execute.c b/src/box/execute.c
index 7da79e602518c805ef03fc28c133ed373cce54b3..0bb678820d2c534d820980e092f41bfa55d2498a 100644
--- a/src/box/execute.c
+++ b/src/box/execute.c
@@ -195,6 +195,15 @@ sql_unprepare_ext(uint32_t stmt_id, uint64_t session_id)
 		diag_set(ClientError, ER_WRONG_QUERY_ID, stmt_id);
 		return -1;
 	}
+	struct sql_stmt *stmt = sql_stmt_cache_find(stmt_id);
+	if (stmt == NULL) {
+		diag_set(ClientError, ER_WRONG_QUERY_ID, stmt_id);
+		return -1;
+	}
+	if (sql_stmt_busy(stmt)) {
+		diag_set(ClientError, ER_SQL_STATEMENT_BUSY, stmt_id);
+		return -1;
+	}
 	session_remove_stmt_id(session, stmt_id);
 	sql_stmt_unref(stmt_id);
 	return 0;
diff --git a/test/box/error.result b/test/box/error.result
index fc54b7901b8ec83c46ca348e8cde5a4bb8429e24..b8d0a1e749020399a2ae08ef91acbe6719b34343 100644
--- a/test/box/error.result
+++ b/test/box/error.result
@@ -489,6 +489,7 @@ t;
  |   268: box.error.ILLEGAL_OPTIONS
  |   269: box.error.ILLEGAL_OPTIONS_FORMAT
  |   270: box.error.CANT_GENERATE
+ |   271: box.error.SQL_STATEMENT_BUSY
  |   272: box.error.SCHEMA_UPGRADE_IN_PROGRESS
  |   274: box.error.UNCONFIGURED
  | ...