diff --git a/src/box/index.cc b/src/box/index.cc
index 4c4c45d81bc27156417604b805acfd2a514b50a5..874c93df84ea465e8c4c310777cd2e6d5284e15a 100644
--- a/src/box/index.cc
+++ b/src/box/index.cc
@@ -34,6 +34,7 @@
 #include "tuple.h"
 #include "say.h"
 #include "exception.h"
+#include "schema.h"
 
 STRS(iterator_type, ITERATOR_TYPE);
 
@@ -102,6 +103,7 @@ primary_key_validate(struct key_def *key_def, const char *key,
 
 Index::Index(struct key_def *key_def_arg)
 	:key_def(key_def_dup(key_def_arg)),
+	sc_version(::sc_version++),
 	m_position(NULL)
 {}
 
@@ -128,6 +130,7 @@ Index::~Index()
 	if (m_position != NULL)
 		m_position->free(m_position);
 	key_def_delete(key_def);
+	::sc_version++;
 }
 
 struct tuple *
diff --git a/src/box/index.h b/src/box/index.h
index 6adb06236138fd1ba60e85e684329b81bfb26f32..739021102aa6b8924e2be9f809ec7fd83303d61c 100644
--- a/src/box/index.h
+++ b/src/box/index.h
@@ -84,6 +84,10 @@ struct iterator {
 	struct tuple *(*next)(struct iterator *);
 	void (*free)(struct iterator *);
 	void (*close)(struct iterator *);
+	/* optional parameters used in lua */
+	int sc_version;
+	uint32_t space_id;
+	uint32_t index_id;
 };
 
 static inline void
@@ -140,6 +144,8 @@ class Index: public Object {
 public:
 	/* Description of a possibly multipart key. */
 	struct key_def *key_def;
+	/* Schema version on index construction moment */
+	int sc_version;
 
 protected:
 	/**
diff --git a/src/box/lua/index.cc b/src/box/lua/index.cc
index 0371fd0990de3d0659b61b0a3292cc32d9e467b9..543647fadf87779b634a498d114d7ae6ecbdcfd7 100644
--- a/src/box/lua/index.cc
+++ b/src/box/lua/index.cc
@@ -95,6 +95,9 @@ boxffi_index_iterator(uint32_t space_id, uint32_t index_id, int type,
 		key_validate(index->key_def, itype, key, part_count);
 		it = index->allocIterator();
 		index->initIterator(it, itype, key, part_count);
+		it->sc_version = sc_version;
+		it->space_id = space_id;
+		it->index_id = index_id;
 		return it;
 	} catch (Exception *) {
 		if (it)
@@ -104,6 +107,23 @@ boxffi_index_iterator(uint32_t space_id, uint32_t index_id, int type,
 	}
 }
 
+struct tuple*
+boxffi_iterator_next(struct iterator *itr)
+{
+	if (itr->sc_version != sc_version) {
+		try {
+			Index *index = check_index(itr->space_id, itr->index_id);
+			if (index->sc_version > itr->sc_version)
+				return NULL;
+			itr->sc_version = sc_version;
+		} catch (Exception *) {
+			/* space or index does not exist, nothing to fetch */
+			return NULL;
+		}
+	}
+	return itr->next(itr);
+}
+
 /* }}} */
 
 void
diff --git a/src/box/lua/index.h b/src/box/lua/index.h
index 2ea1a53e68237d1815a6a921171f153bd0c73658..d442f0016044c06c806956730160ba75a43ea9b0 100644
--- a/src/box/lua/index.h
+++ b/src/box/lua/index.h
@@ -52,6 +52,9 @@ struct iterator *
 boxffi_index_iterator(uint32_t space_id, uint32_t index_id, int type,
 		      const char *key);
 
+struct tuple*
+boxffi_iterator_next(struct iterator *itr);
+
 #if defined(__cplusplus)
 } /* extern "C" */
 #endif /* defined(__cplusplus) */
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 7e6798a1c9bad38380145a3c553fd68a7659fc39..fb877f8a9bf2b8638e3c8e41a2eaf35b38c68338 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -16,6 +16,9 @@ ffi.cdef[[
         struct tuple *(*next)(struct iterator *);
         void (*free)(struct iterator *);
         void (*close)(struct iterator *);
+        int sc_version;
+        uint32_t space_id;
+        uint32_t index_id;
     };
     size_t
     boxffi_index_len(uint32_t space_id, uint32_t index_id);
@@ -24,6 +27,8 @@ ffi.cdef[[
     struct iterator *
     boxffi_index_iterator(uint32_t space_id, uint32_t index_id, int type,
                   const char *key);
+    struct tuple *
+    boxffi_iterator_next(struct iterator *itr);
 
     struct port;
     struct port_ffi
@@ -319,7 +324,7 @@ local iterator_gen = function(param, state)
         error('usage gen(param, state)')
     end
     -- next() modifies state in-place
-    local tuple = state.next(state)
+    local tuple = builtin.boxffi_iterator_next(state)
     if tuple ~= nil then
         return state, box.tuple.bless(tuple) -- new state, value
     else
diff --git a/src/box/schema.cc b/src/box/schema.cc
index a1b5c2e819a7b16ea615d77d1993da66b4353ea9..5ad3637e0f39e394a6a8fb2582759588666cbc47 100644
--- a/src/box/schema.cc
+++ b/src/box/schema.cc
@@ -153,6 +153,7 @@ space_cache_replace(struct space *space)
 		panic_syserror("Out of memory for the data "
 			       "dictionary cache.");
 	}
+	sc_version++;
 	/*
 	 * Must be after the space is put into the hash, since
 	 * box.schema.space.bless() uses hash look up to find the
diff --git a/test/big/iterator.result b/test/big/iterator.result
index b8f720cbd9bb8fff2fb062a0e0e06e3d0199a64d..8bd1e9c92faf0ee52eb75e576bf673d56996fe93 100644
--- a/test/big/iterator.result
+++ b/test/big/iterator.result
@@ -893,6 +893,21 @@ space.index['primary']:pairs(function() end, { iterator = box.index.EQ })
 ---
 - error: 'builtin/msgpackffi.lua:258: can not encode Lua type: ''function'''
 ...
+-- Check that iterators successfully invalidated when index deleted
+gen, param, state = space.index['i1']:pairs(nil, { iterator = box.index.GE })
+---
+...
+index_space = box.space[box.schema.INDEX_ID]
+---
+...
+index_space:delete{space.id, space.index['i1'].id}
+---
+- [512, 1, 'i1', 'tree', 0, 1, 1, 'str']
+...
+gen(param, state)
+---
+- null
+...
 space:drop()
 ---
 ...
diff --git a/test/big/iterator.test.lua b/test/big/iterator.test.lua
index 9dd7822af522d1561f8c7e702917bc0dbcdbf486..4271ad50f1d8f1d2aebeea0b0fe69e638a961410 100644
--- a/test/big/iterator.test.lua
+++ b/test/big/iterator.test.lua
@@ -161,4 +161,11 @@ iterate('tweedledum', 'i5', 1, 3, box.index.EQ, 'sid_005', 'tid_995', 'a')
 space.index['primary']:pairs({}, {iterator = -666 })
 -- Test cases for #123: box.index.count does not check arguments properly
 space.index['primary']:pairs(function() end, { iterator = box.index.EQ })
+
+-- Check that iterators successfully invalidated when index deleted
+gen, param, state = space.index['i1']:pairs(nil, { iterator = box.index.GE })
+index_space = box.space[box.schema.INDEX_ID]
+index_space:delete{space.id, space.index['i1'].id}
+gen(param, state)
+
 space:drop()