diff --git a/include/box/box.h b/include/box/box.h
index fb78ec3a82f25eb71dd6177e7193dfae463586d6..43bd31b6e5b28baaec08e00ffaf0b2a3c4a7c8ae 100644
--- a/include/box/box.h
+++ b/include/box/box.h
@@ -93,4 +93,11 @@ const char *box_status(void);
  */
 void
 box_leave_local_standby_mode(void *data __attribute__((unused)));
+
+enum {
+	BOX_SPACE_MAX = UINT32_MAX,
+	BOX_INDEX_MAX = 10,
+	BOX_FIELD_MAX = UINT32_MAX
+};
+
 #endif /* INCLUDES_TARANTOOL_BOX_H */
diff --git a/include/errcode.h b/include/errcode.h
index 2140e84ea70a00017d0c4f0df4ac505e54aa1626..b0dac16fb879226014fd6a3b0a52a2f0d03405df 100644
--- a/include/errcode.h
+++ b/include/errcode.h
@@ -97,17 +97,17 @@ enum { TNT_ERRMSG_MAX = 512 };
 	/* 42 */_(ER_SPLICE,			2, "Field SPLICE error: %s") \
 	/* 43 */_(ER_TUPLE_IS_TOO_LONG,		2, "Tuple is too long %u") \
 	/* 44 */_(ER_UNKNOWN_UPDATE_OP,		2, "Unknown UPDATE operation") \
-	/* 45 */_(ER_EXACT_MATCH,		2, "Partial key in an exact match (key field count: %d, expected: %d)") \
+	/* 45 */_(ER_EXACT_MATCH,		2, "Partial key in an exact match (key field count: %u, expected: %u)") \
 	/* 46 */_(ER_UNUSED46,			2, "Unused46") \
-	/* 47 */_(ER_KEY_PART_COUNT,		2, "Key part count %d is greater than index part count %d") \
+	/* 47 */_(ER_KEY_PART_COUNT,		2, "Key part count %u is greater than index part count %u") \
 	/* 48 */_(ER_PROC_RET,			2, "Return type '%s' is not supported in the binary protocol") \
-	/* 49 */_(ER_TUPLE_NOT_FOUND,		2, "Tuple doesn't exist in index %d") \
+	/* 49 */_(ER_TUPLE_NOT_FOUND,		2, "Tuple doesn't exist in index %u") \
 	/* 50 */_(ER_NO_SUCH_PROC,		2, "Procedure '%.*s' is not defined") \
 	/* 51 */_(ER_PROC_LUA,			2, "Lua error: %s") \
 	/* 52 */_(ER_SPACE_DISABLED,		2, "Space %u is disabled") \
 	/* 53 */_(ER_NO_SUCH_INDEX,		2, "No index #%u is defined in space %u") \
 	/* 54 */_(ER_NO_SUCH_FIELD,		2, "Field %u was not found in the tuple") \
-	/* 55 */_(ER_TUPLE_FOUND,		2, "Duplicate key exists in unique index %d") \
+	/* 55 */_(ER_TUPLE_FOUND,		2, "Duplicate key exists in unique index %u") \
 	/* 56 */_(ER_UNUSED,		        2, "") \
 	/* 57 */_(ER_NO_SUCH_SPACE,		2, "Space %u does not exist")
 
diff --git a/src/box/box.m b/src/box/box.m
index af8b195ff58e6ca1059176bdb9e3a16b6d1bbb38..9330a9771e86ee637693134c3d525a5ac7d1eb23 100644
--- a/src/box/box.m
+++ b/src/box/box.m
@@ -484,7 +484,7 @@ box_cat(const char *filename)
 
 static void
 snapshot_write_tuple(struct log_io *l, struct fio_batch *batch,
-		     unsigned n, struct tuple *tuple)
+		     u32 n, struct tuple *tuple)
 {
 	struct box_snap_row header;
 	header.space = n;
diff --git a/src/box/box_lua.m b/src/box/box_lua.m
index cfe36c7dac8c105ec3c21d87a805ac3a9d508e49..caf5ecc87e85cb8343f72dfa12bfc36c3bc3fe80 100644
--- a/src/box/box_lua.m
+++ b/src/box/box_lua.m
@@ -160,8 +160,8 @@ lbox_tuple_slice(struct lua_State *L)
 		luaL_error(L, "tuple.slice(): start must be less than end");
 
 	u8 *field = tuple->data;
-	int fieldno = 0;
-	int stop = end - 1;
+	u32 fieldno = 0;
+	u32 stop = end - 1;
 
 	while (field < tuple->data + tuple->bsize) {
 		size_t len = load_varint32((const void **) &field);
@@ -724,7 +724,7 @@ lbox_create_iterator(struct lua_State *L)
 	int argc = lua_gettop(L);
 	/* Create a new iterator. */
 	enum iterator_type type;
-	int field_count;
+	u32 field_count;
 	void *key;
 	if (argc == 1 || (argc == 2 && lua_type(L, 2) == LUA_TNIL)) {
 		/*
@@ -753,7 +753,7 @@ lbox_create_iterator(struct lua_State *L)
 			/* Single or multi- part key. */
 			field_count = argc - 2;
 			struct tbuf *data = tbuf_new(fiber->gc_pool);
-			for (int i = 0; i < field_count; i++) {
+			for (u32 i = 0; i < field_count; i++) {
 				enum field_data_type type = UNKNOWN;
 				if (i < index->key_def->part_count) {
 					type = index->key_def->parts[i].type;
@@ -855,7 +855,7 @@ lbox_index_count(struct lua_State *L)
 		luaL_error(L, "index.count(): one or more arguments expected");
 	/* preparing single or multi-part key */
 	void *key;
-	int key_part_count;
+	u32 key_part_count;
 	if (argc == 1 && lua_type(L, 2) == LUA_TUSERDATA) {
 		/* Searching by tuple. */
 		struct tuple *tuple = lua_checktuple(L, 2);
@@ -865,7 +865,7 @@ lbox_index_count(struct lua_State *L)
 		/* Single or multi- part key. */
 		key_part_count = argc;
 		struct tbuf *data = tbuf_new(fiber->gc_pool);
-		for (int i = 0; i < argc; ++i) {
+		for (u32 i = 0; i < argc; ++i) {
 			enum field_data_type type = UNKNOWN;
 			if (i < index->key_def->part_count) {
 				type = index->key_def->parts[i].type;
diff --git a/src/box/box_lua_space.m b/src/box/box_lua_space.m
index 5bde6a03ecd12d4d496aec704d96d5c38771a1cc..a86fef2bb90e16e739bd138b88e81b2911e3bdc0 100644
--- a/src/box/box_lua_space.m
+++ b/src/box/box_lua_space.m
@@ -88,7 +88,7 @@ lbox_pushspace(struct lua_State *L, struct space *space)
 		lua_pushstring(L, "key_field");
 		lua_newtable(L);
 
-		for (int j = 0; j < space->key_defs[i].part_count; j++) {
+		for (u32 j = 0; j < space->key_defs[i].part_count; j++) {
 			lua_pushnumber(L, j);
 			lua_newtable(L);
 
diff --git a/src/box/hash_index.m b/src/box/hash_index.m
index d72fed45c241ce04639ca0e8ce25216c257f27cb..f351a8ac8e155001e77377844c0357fffb41353b 100644
--- a/src/box/hash_index.m
+++ b/src/box/hash_index.m
@@ -309,7 +309,7 @@ int32_tuple_to_node(struct tuple *tuple, struct key_def *key_def)
 	return mh_size(int_hash);
 }
 
-- (struct tuple *) findByKey: (const void *) key :(int) part_count
+- (struct tuple *) findByKey: (const void *) key :(u32) part_count
 {
 	assert(key_def->is_unique);
 	check_key_parts(key_def, part_count, false);
@@ -388,7 +388,7 @@ int32_tuple_to_node(struct tuple *tuple, struct key_def *key_def)
 }
 
 - (void) initIterator: (struct iterator *) ptr :(enum iterator_type) type
-                        :(void *) key :(int) part_count
+			:(void *) key :(u32) part_count
 {
 	assert(ptr->free == hash_iterator_free);
 	struct hash_i32_iterator *it = (struct hash_i32_iterator *) ptr;
@@ -474,7 +474,7 @@ int64_tuple_to_node(struct tuple *tuple, struct key_def *key_def)
 	return mh_size(int64_hash);
 }
 
-- (struct tuple *) findByKey: (const void *) key :(int) part_count
+- (struct tuple *) findByKey: (const void *) key :(u32) part_count
 {
 	assert(key_def->is_unique);
 	check_key_parts(key_def, part_count, false);
@@ -551,7 +551,7 @@ int64_tuple_to_node(struct tuple *tuple, struct key_def *key_def)
 
 
 - (void) initIterator: (struct iterator *) ptr :(enum iterator_type) type
-                        :(void *) key :(int) part_count
+			:(void *) key :(u32) part_count
 {
 	(void) part_count;
 	assert(ptr->free == hash_iterator_free);
@@ -632,7 +632,7 @@ lstrptr_tuple_to_node(struct tuple *tuple, struct key_def *key_def)
 	return mh_size(str_hash);
 }
 
-- (struct tuple *) findByKey: (const void *) key :(int) part_count
+- (struct tuple *) findByKey: (const void *) key :(u32) part_count
 {
 	assert(key_def->is_unique);
 	check_key_parts(key_def, part_count, false);
@@ -712,7 +712,7 @@ lstrptr_tuple_to_node(struct tuple *tuple, struct key_def *key_def)
 
 - (void) initIterator: (struct iterator *) ptr
 			:(enum iterator_type) type
-                        :(void *) key :(int) part_count
+			:(void *) key :(u32) part_count
 {
 	(void) part_count;
 
diff --git a/src/box/index.h b/src/box/index.h
index 7d394fb1b22783bfa91b0269b7f0e56e889d06e4..0db892bf9fb771efc4522b16040e113377b92bfe 100644
--- a/src/box/index.h
+++ b/src/box/index.h
@@ -40,7 +40,7 @@ struct space;
  * since there is a mismatch between enum name (STRING) and type
  * name literal ("STR"). STR is already used as Objective C type.
  */
-enum field_data_type { UNKNOWN = -1, NUM = 0, NUM64, STRING, field_data_type_MAX };
+enum field_data_type { UNKNOWN = 0, NUM, NUM64, STRING, field_data_type_MAX };
 extern const char *field_data_type_strs[];
 
 #define INDEX_TYPE(_)                                             \
@@ -96,7 +96,7 @@ struct iterator {
 
 /** Descriptor of a single part in a multipart key. */
 struct key_part {
-	int fieldno;
+	u32 fieldno;
 	enum field_data_type type;
 };
 
@@ -115,12 +115,12 @@ struct key_def {
 	 */
 	u32 *cmp_order;
 	/* The size of the 'parts' array. */
-	int part_count;
+	u32 part_count;
 	/*
 	 * The size of 'cmp_order' array (= max fieldno in 'parts'
 	 * array).
 	 */
-	int max_fieldno;
+	u32 max_fieldno;
 	bool is_unique;
 	enum index_type type;
 };
@@ -202,7 +202,7 @@ enum dup_replace_mode {
 - (size_t) size;
 - (struct tuple *) min;
 - (struct tuple *) max;
-- (struct tuple *) findByKey: (const void *) key :(int) part_count;
+- (struct tuple *) findByKey: (const void *) key :(u32) part_count;
 - (struct tuple *) findByTuple: (struct tuple *) tuple;
 - (struct tuple *) replace: (struct tuple *) old_tuple
 			  :(struct tuple *) new_tuple
@@ -214,11 +214,11 @@ enum dup_replace_mode {
 - (struct iterator *) allocIterator;
 - (void) initIterator: (struct iterator *) iterator
 		     :(enum iterator_type) type
-		     :(void *) key :(int) part_count;
+		     :(void *) key :(u32) part_count;
 @end
 
 void
-check_key_parts(const struct key_def *key_def, int part_count,
+check_key_parts(const struct key_def *key_def, u32 part_count,
 		bool partial_key_allowed);
 
 uint32_t
diff --git a/src/box/index.m b/src/box/index.m
index c105cb4a30c7d5a0d7b6c79679f61fd7f16e6458..36e63924b1e6868251464dd6fb659dfc313274de 100644
--- a/src/box/index.m
+++ b/src/box/index.m
@@ -38,7 +38,7 @@ static struct index_traits index_traits = {
 	.allows_partial_key = false,
 };
 
-const char *field_data_type_strs[] = {"NUM", "NUM64", "STR", "\0"};
+const char *field_data_type_strs[] = {"UNKNOWN", "NUM", "NUM64", "STR", "\0"};
 STRS(index_type, INDEX_TYPE);
 STRS(iterator_type, ITERATOR_TYPE);
 
@@ -46,7 +46,7 @@ STRS(iterator_type, ITERATOR_TYPE);
 
 void
 check_key_parts(const struct key_def *key_def,
-		int part_count, bool partial_key_allowed)
+		u32 part_count, bool partial_key_allowed)
 {
 	if (part_count > key_def->part_count)
 		tnt_raise(ClientError, :ER_KEY_PART_COUNT,
@@ -176,7 +176,7 @@ replace_check_dup(struct tuple *old_tuple,
 	return NULL;
 }
 
-- (struct tuple *) findByKey: (const void *) key :(int) part_count
+- (struct tuple *) findByKey: (const void *) key :(u32) part_count
 {
 	(void) key;
 	(void) part_count;
@@ -211,7 +211,7 @@ replace_check_dup(struct tuple *old_tuple,
 
 - (void) initIterator: (struct iterator *) iterator
 	:(enum iterator_type) type
-	:(void *) key :(int) part_count
+	:(void *) key :(u32) part_count
 {
 	(void) iterator;
 	(void) type;
diff --git a/src/box/request.m b/src/box/request.m
index 160297825bd41ee30f3f2c56d5d873eb7c8e97b1..9d188dde50467df7e2a80e654923eefea75cbbd9 100644
--- a/src/box/request.m
+++ b/src/box/request.m
@@ -50,7 +50,7 @@ read_key(struct tbuf *data, void **key_ptr, u32 *key_part_count_ptr)
 	if (key_part_count) {
 		key = read_field(data);
 		/* advance remaining fields of a key */
-		for (int i = 1; i < key_part_count; i++)
+		for (u32 i = 1; i < key_part_count; i++)
 			read_field(data);
 	}
 
diff --git a/src/box/space.h b/src/box/space.h
index aff311369bd59b79c05bcf286b574ffaf70babc9..e06fbf8410e595be7f8726cd440967226ed7eaab 100644
--- a/src/box/space.h
+++ b/src/box/space.h
@@ -31,12 +31,9 @@
 #include "index.h"
 #include <exception.h>
 
-struct tarantool_cfg;
-
+#include <box/box.h>
 
-enum {
-	BOX_INDEX_MAX = 10,
-};
+struct tarantool_cfg;
 
 struct space {
 	Index *index[BOX_INDEX_MAX];
@@ -45,7 +42,7 @@ struct space {
 	 * @sa max_fieldno). If set, Each tuple
 	 * must have exactly this many fields.
 	 */
-	int arity;
+	u32 arity;
 
 	/**
 	 * The number of indexes in the space.
@@ -53,7 +50,7 @@ struct space {
 	 * It is equal to the number of non-nil members of the index
 	 * array and defines the key_defs array size as well.
 	 */
-	int key_count;
+	u32 key_count;
 
 	/**
 	 * The descriptors for all indexes that belong to the space.
@@ -75,15 +72,15 @@ struct space {
 	 * Each tuple in this space must have, therefore, at least
 	 * field_count fields.
 	 */
-	int max_fieldno;
+	u32 max_fieldno;
 
 	/** Space number. */
-	i32 no;
+	u32 no;
 };
 
 
 /** Get space ordinal number. */
-static inline i32 space_n(struct space *sp) { return sp->no; }
+static inline u32 space_n(struct space *sp) { return sp->no; }
 
 /**
  * @brief A single method to handle REPLACE, DELETE and UPDATE.
@@ -186,16 +183,16 @@ space_validate_tuple(struct space *sp, struct tuple *new_tuple);
  * @return NULL if index not found.
  */
 static inline Index *
-space_index(struct space *sp, int index_no)
+space_index(struct space *sp, u32 index_no)
 {
-	if (index_no >= 0 && index_no < BOX_INDEX_MAX)
+	if (index_no < BOX_INDEX_MAX)
 		return sp->index[index_no];
 	return NULL;
 }
 
 /** Set index by index no. */
 void
-space_set_index(struct space *sp, int index_no, Index *idx);
+space_set_index(struct space *sp, u32 index_no, Index *idx);
 
 /**
  * Call a visitor function on every enabled space.
@@ -208,10 +205,10 @@ space_foreach(void (*func)(struct space *sp, void *udata), void *udata);
  *
  * @return NULL if space not found, otherwise space object.
  */
-struct space *space_by_n(i32 space_no);
+struct space *space_by_n(u32 space_no);
 
 static inline struct space *
-space_find(i32 space_no)
+space_find(u32 space_no)
 {
 	struct space *s = space_by_n(space_no);
 	if (s)
@@ -222,32 +219,32 @@ space_find(i32 space_no)
 
 
 /** Get key_def ordinal number. */
-static inline int
+static inline u32
 key_def_n(struct space *sp, struct key_def *kp)
 {
 	assert(kp >= sp->key_defs && kp < (sp->key_defs + sp->key_count));
 	return kp - sp->key_defs;
 }
 
-static inline int
+static inline u32
 space_max_fieldno(struct space *sp)
 {
 	return sp->max_fieldno;
 }
 
 static inline enum field_data_type
-space_field_type(struct space *sp, int no)
+space_field_type(struct space *sp, u32 no)
 {
 	return sp->field_types[no];
 }
 
 
 struct space *
-space_create(i32 space_no, struct key_def *key_defs, int key_count, int arity);
+space_create(u32 space_no, struct key_def *key_defs, u32 key_count, u32 arity);
 
 
 /** Get index ordinal number in space. */
-static inline int
+static inline u32
 index_n(Index *index)
 {
 	return key_def_n(index->space, index->key_def);
@@ -273,7 +270,8 @@ extern bool primary_indexes_enabled;
 
 void space_init(void);
 void space_free(void);
-i32 check_spaces(struct tarantool_cfg *conf);
+int
+check_spaces(struct tarantool_cfg *conf);
 /* Build secondary keys. */
 void begin_build_primary_indexes(void);
 void end_build_primary_indexes(void);
@@ -281,7 +279,7 @@ void build_secondary_indexes(void);
 
 
 static inline Index *
-index_find(struct space *sp, int index_no)
+index_find(struct space *sp, u32 index_no)
 {
 	Index *idx = space_index(sp, index_no);
 	if (idx == NULL)
diff --git a/src/box/space.m b/src/box/space.m
index 179ba6510de0f7cccecb62fd85411485d1444b4b..0a7950b19190c0a5b822a432a63659f2d3a7a81f 100644
--- a/src/box/space.m
+++ b/src/box/space.m
@@ -38,13 +38,15 @@
 #include <palloc.h>
 #include <assoc.h>
 
+#include <box/box.h>
+
 static struct mh_i32ptr_t *spaces;
 
 bool secondary_indexes_enabled = false;
 bool primary_indexes_enabled = false;
 
 struct space *
-space_create(i32 space_no, struct key_def *key_defs, int key_count, int arity)
+space_create(u32 space_no, struct key_def *key_defs, u32 key_count, u32 arity)
 {
 
 	struct space *space = space_by_n(space_no);
@@ -66,7 +68,7 @@ space_create(i32 space_no, struct key_def *key_defs, int key_count, int arity)
 
 /* return space by its number */
 struct space *
-space_by_n(i32 n)
+space_by_n(u32 n)
 {
 	const struct mh_i32ptr_node_t node = { .key = n };
 	mh_int_t space = mh_i32ptr_get(spaces, &node, NULL, NULL);
@@ -106,9 +108,9 @@ space_foreach(void (*func)(struct space *sp, void *udata), void *udata) {
 
 /** Set index by index no */
 void
-space_set_index(struct space *sp, int index_no, Index *idx)
+space_set_index(struct space *sp, u32 index_no, Index *idx)
 {
-	assert(index_no >= 0 && index_no < BOX_INDEX_MAX);
+	assert(index_no < BOX_INDEX_MAX);
 	sp->index[index_no] = idx;
 }
 
@@ -124,7 +126,7 @@ struct tuple *
 space_replace(struct space *sp, struct tuple *old_tuple,
 	      struct tuple *new_tuple, enum dup_replace_mode mode)
 {
-	int i = 0;
+	u32 i = 0;
 	@try {
 		/* Update the primary key */
 		Index *pk = sp->index[0];
@@ -137,7 +139,7 @@ space_replace(struct space *sp, struct tuple *old_tuple,
 		old_tuple = [pk replace: old_tuple :new_tuple :mode];
 
 		assert(old_tuple || new_tuple);
-		int n = index_count(sp);
+		u32 n = index_count(sp);
 		/* Update secondary keys */
 		for (i = i + 1; i < n; i++) {
 			Index *index = sp->index[i];
@@ -146,8 +148,8 @@ space_replace(struct space *sp, struct tuple *old_tuple,
 		return old_tuple;
 	} @catch (tnt_Exception *e) {
 		/* Rollback all changes */
-		for (i = i - 1; i >= 0;  i--) {
-			Index *index = sp->index[i];
+		for (; i > 0; i--) {
+			Index *index = sp->index[i-1];
 			[index replace: new_tuple: old_tuple: DUP_INSERT];
 		}
 		@throw;
@@ -168,7 +170,7 @@ space_validate_tuple(struct space *sp, struct tuple *new_tuple)
 
 	/* Sweep through the tuple and check the field sizes. */
 	const u8 *data = new_tuple->data;
-	for (int f = 0; f < sp->max_fieldno; ++f) {
+	for (u32 f = 0; f < sp->max_fieldno; ++f) {
 		/* Get the size of the current field and advance. */
 		u32 len = load_varint32((const void **) &data);
 		data += len;
@@ -197,8 +199,7 @@ space_free(void)
 		struct space *space = mh_i32ptr_node(spaces, i)->val;
 		mh_i32ptr_del(spaces, i, NULL, NULL);
 
-		int j;
-		for (j = 0 ; j < space->key_count; j++) {
+		for (u32 j = 0 ; j < space->key_count; j++) {
 			Index *index = space->index[j];
 			[index free];
 			key_free(&space->key_defs[j]);
@@ -222,7 +223,7 @@ key_init(struct key_def *def, struct tarantool_cfg_space_index *cfg_index)
 		panic("Wrong index type: %s", cfg_index->type);
 
 	/* Calculate key part count and maximal field number. */
-	for (int k = 0; cfg_index->key_field[k] != NULL; ++k) {
+	for (u32 k = 0; cfg_index->key_field[k] != NULL; ++k) {
 		typeof(cfg_index->key_field[k]) cfg_key = cfg_index->key_field[k];
 
 		if (cfg_key->fieldno == -1) {
@@ -246,10 +247,12 @@ key_init(struct key_def *def, struct tarantool_cfg_space_index *cfg_index)
 	if (def->cmp_order == NULL) {
 		panic("can't allocate def cmp_order array for index");
 	}
-	memset(def->cmp_order, -1, def->max_fieldno * sizeof(u32));
+	for (u32 fieldno = 0; fieldno < def->max_fieldno; fieldno++) {
+		def->cmp_order[fieldno] = BOX_FIELD_MAX;
+	}
 
 	/* fill fields and compare order */
-	for (int k = 0; cfg_index->key_field[k] != NULL; ++k) {
+	for (u32 k = 0; cfg_index->key_field[k] != NULL; ++k) {
 		typeof(cfg_index->key_field[k]) cfg_key = cfg_index->key_field[k];
 
 		if (cfg_key->fieldno == -1) {
@@ -261,7 +264,7 @@ key_init(struct key_def *def, struct tarantool_cfg_space_index *cfg_index)
 		def->parts[k].fieldno = cfg_key->fieldno;
 		def->parts[k].type = STR2ENUM(field_data_type, cfg_key->type);
 		/* fill compare order */
-		if (def->cmp_order[cfg_key->fieldno] == -1)
+		if (def->cmp_order[cfg_key->fieldno] == BOX_FIELD_MAX)
 			def->cmp_order[cfg_key->fieldno] = k;
 	}
 	def->is_unique = cfg_index->unique;
@@ -277,8 +280,8 @@ key_init(struct key_def *def, struct tarantool_cfg_space_index *cfg_index)
 static void
 space_init_field_types(struct space *space)
 {
-	int i, max_fieldno;
-	int key_count = space->key_count;
+	u32 i, max_fieldno;
+	u32 key_count = space->key_count;
 	struct key_def *key_defs = space->key_defs;
 
 	/* find max max field no */
@@ -289,15 +292,12 @@ space_init_field_types(struct space *space)
 
 	/* alloc & init field type info */
 	space->max_fieldno = max_fieldno;
-	space->field_types = malloc(max_fieldno * sizeof(enum field_data_type));
-	for (i = 0; i < max_fieldno; i++) {
-		space->field_types[i] = UNKNOWN;
-	}
+	space->field_types = calloc(max_fieldno, sizeof(enum field_data_type));
 
 	/* extract field type info */
 	for (i = 0; i < key_count; i++) {
 		struct key_def *def = &key_defs[i];
-		for (int pi = 0; pi < def->part_count; pi++) {
+		for (u32 pi = 0; pi < def->part_count; pi++) {
 			struct key_part *part = &def->parts[pi];
 			assert(part->fieldno < max_fieldno);
 			space->field_types[part->fieldno] = part->type;
@@ -308,7 +308,7 @@ space_init_field_types(struct space *space)
 	/* validate field type info */
 	for (i = 0; i < key_count; i++) {
 		struct key_def *def = &key_defs[i];
-		for (int pi = 0; pi < def->part_count; pi++) {
+		for (u32 pi = 0; pi < def->part_count; pi++) {
 			struct key_part *part = &def->parts[pi];
 			assert(space->field_types[part->fieldno] == part->type);
 		}
@@ -325,7 +325,7 @@ space_config()
 	}
 
 	/* fill box spaces */
-	for (int i = 0; cfg.space[i] != NULL; ++i) {
+	for (u32 i = 0; cfg.space[i] != NULL; ++i) {
 		tarantool_cfg_space *cfg_space = cfg.space[i];
 
 		if (!CNF_STRUCT_DEFINED(cfg_space) || !cfg_space->enabled)
@@ -335,19 +335,20 @@ space_config()
 
 		struct space *space = space_by_n(i);
 		if (space)
-			panic("space %i is already exists", i);
+			panic("space %u is already exists", i);
 
 		space = calloc(sizeof(struct space), 1);
 		space->no = i;
 
-		space->arity = cfg_space->cardinality;
+		space->arity = (cfg_space->cardinality != -1) ?
+					cfg_space->cardinality : 0;
 		/*
 		 * Collect key/field info. We need aggregate
 		 * information on all keys before we can create
 		 * indexes.
 		 */
 		space->key_count = 0;
-		for (int j = 0; cfg_space->index[j] != NULL; ++j) {
+		for (u32 j = 0; cfg_space->index[j] != NULL; ++j) {
 			++space->key_count;
 		}
 
@@ -357,14 +358,14 @@ space_config()
 		if (space->key_defs == NULL) {
 			panic("can't allocate key def array");
 		}
-		for (int j = 0; cfg_space->index[j] != NULL; ++j) {
+		for (u32 j = 0; cfg_space->index[j] != NULL; ++j) {
 			typeof(cfg_space->index[j]) cfg_index = cfg_space->index[j];
 			key_init(&space->key_defs[j], cfg_index);
 		}
 		space_init_field_types(space);
 
 		/* fill space indexes */
-		for (int j = 0; cfg_space->index[j] != NULL; ++j) {
+		for (u32 j = 0; cfg_space->index[j] != NULL; ++j) {
 			typeof(cfg_space->index[j]) cfg_index = cfg_space->index[j];
 			enum index_type type = STR2ENUM(index_type, cfg_index->type);
 			struct key_def *key_def = &space->key_defs[j];
@@ -377,7 +378,7 @@ space_config()
 		const struct mh_i32ptr_node_t node =
 			{ .key = space->no, .val = space };
 		mh_i32ptr_put(spaces, &node, NULL, NULL, NULL);
-		say_info("space %i successfully configured", i);
+		say_info("space %u successfully configured", i);
 	}
 }
 
@@ -432,7 +433,7 @@ build_secondary_indexes(void)
 		say_info("Building secondary keys in space %d...", space->no);
 
 		Index *pk = space->index[0];
-		for (int j = 1; j < space->key_count; j++) {
+		for (u32 j = 1; j < space->key_count; j++) {
 			Index *index = space->index[j];
 			[index build: pk];
 		}
@@ -444,7 +445,7 @@ build_secondary_indexes(void)
 	secondary_indexes_enabled = true;
 }
 
-i32
+int
 check_spaces(struct tarantool_cfg *conf)
 {
 	/* exit if no spaces are configured */
@@ -455,6 +456,12 @@ check_spaces(struct tarantool_cfg *conf)
 	for (size_t i = 0; conf->space[i] != NULL; ++i) {
 		typeof(conf->space[i]) space = conf->space[i];
 
+		if (i >= BOX_SPACE_MAX) {
+			out_warning(0, "(space = %zu) invalid id, (maximum=%u)",
+				    i, BOX_SPACE_MAX);
+			return -1;
+		}
+
 		if (!CNF_STRUCT_DEFINED(space)) {
 			/* space undefined, skip it */
 			continue;
@@ -466,7 +473,7 @@ check_spaces(struct tarantool_cfg *conf)
 		}
 
 		if (conf->memcached_port && i == conf->memcached_space) {
-			out_warning(0, "Space %i is already used as "
+			out_warning(0, "Space %zu is already used as "
 				    "memcached_space.", i);
 			return -1;
 		}
@@ -479,7 +486,7 @@ check_spaces(struct tarantool_cfg *conf)
 			return -1;
 		}
 
-		int max_key_fieldno = -1;
+		u32 max_key_fieldno = 0;
 
 		/* check spaces indexes */
 		for (size_t j = 0; space->index[j] != NULL; ++j) {
@@ -491,7 +498,7 @@ check_spaces(struct tarantool_cfg *conf)
 			if (j >= BOX_INDEX_MAX) {
 				/* maximum index in space reached */
 				out_warning(0, "(space = %zu index = %zu) "
-					    "too many indexed (%i maximum)", i, j, BOX_INDEX_MAX);
+					    "too many indexed (%u maximum)", i, j, BOX_INDEX_MAX);
 				return -1;
 			}
 
@@ -517,6 +524,14 @@ check_spaces(struct tarantool_cfg *conf)
 					break;
 				}
 
+				if (key->fieldno >= BOX_FIELD_MAX) {
+					/* maximum index in space reached */
+					out_warning(0, "(space = %zu index = %zu) "
+						    "invalid field number (%u maximum)",
+						    i, j, BOX_FIELD_MAX);
+					return -1;
+				}
+
 				/* key must has valid type */
 				if (STR2ENUM(field_data_type, key->type) == field_data_type_MAX) {
 					out_warning(0, "(space = %zu index = %zu) "
@@ -524,8 +539,8 @@ check_spaces(struct tarantool_cfg *conf)
 					return -1;
 				}
 
-				if (max_key_fieldno < key->fieldno) {
-					max_key_fieldno = key->fieldno;
+				if (max_key_fieldno < key->fieldno + 1) {
+					max_key_fieldno = key->fieldno + 1;
 				}
 
 				++key_part_count;
@@ -578,17 +593,17 @@ check_spaces(struct tarantool_cfg *conf)
 		}
 
 		/* Check for index field type conflicts */
-		if (max_key_fieldno >= 0) {
-			char *types = alloca(max_key_fieldno + 1);
-			memset(types, UNKNOWN, max_key_fieldno + 1);
+		if (max_key_fieldno > 0) {
+			char *types = alloca(max_key_fieldno);
+			memset(types, 0, max_key_fieldno);
 			for (size_t j = 0; space->index[j] != NULL; ++j) {
 				typeof(space->index[j]) index = space->index[j];
 				for (size_t k = 0; index->key_field[k] != NULL; ++k) {
 					typeof(index->key_field[k]) key = index->key_field[k];
-					int f = key->fieldno;
-					if (f == -1) {
+					if (key->fieldno == -1)
 						break;
-					}
+
+					u32 f = key->fieldno;
 					enum field_data_type t = STR2ENUM(field_data_type, key->type);
 					assert(t != field_data_type_MAX);
 					if (types[f] != t) {
diff --git a/src/box/tree_index.m b/src/box/tree_index.m
index 3dcb7c8c2d9ae1314676aabfe5d4eb625b3b63a1..d01237ae301cb9269f25fc35ce42f394f51c0aa8 100644
--- a/src/box/tree_index.m
+++ b/src/box/tree_index.m
@@ -187,7 +187,7 @@ struct fixed_node {
 struct key_data
 {
 	const u8 *data;
-	int part_count;
+	u32 part_count;
 	union sparse_part parts[];
 };
 
@@ -199,10 +199,10 @@ struct key_data
  * Find if the field has fixed offset.
  */
 static int
-find_fixed_offset(struct space *space, int fieldno, int skip)
+find_fixed_offset(struct space *space, u32 fieldno, u32 skip)
 {
-	int i = skip;
-	int offset = 0;
+	u32 i = skip;
+	u32 offset = 0;
 
 	while (i < fieldno) {
 		/* if the field is unknown give up on it */
@@ -234,9 +234,9 @@ find_fixed_offset(struct space *space, int fieldno, int skip)
 static u32
 find_first_field(struct key_def *key_def)
 {
-	for (int field = 0; field < key_def->max_fieldno; ++field) {
-		int part = key_def->cmp_order[field];
-		if (part != -1) {
+	for (u32 field = 0; field < key_def->max_fieldno; ++field) {
+		u32 part = key_def->cmp_order[field];
+		if (part != BOX_FIELD_MAX) {
 			return field;
 		}
 	}
@@ -253,15 +253,15 @@ find_tree_type(struct space *space, struct key_def *key_def)
 	int fixed = 1;
 
 	/* Scan for the first tuple field used by the index */
-	int field = find_first_field(key_def);
+	u32 field = find_first_field(key_def);
 	if (find_fixed_offset(space, field, 0) < 0) {
 		fixed = 0;
 	}
 
 	/* Check that there are no gaps after the first field */
 	for (; field < key_def->max_fieldno; ++field) {
-		int part = key_def->cmp_order[field];
-		if (part == -1) {
+		u32 part = key_def->cmp_order[field];
+		if (part == BOX_FIELD_MAX) {
 			dense = 0;
 			break;
 		}
@@ -286,9 +286,9 @@ static bool
 key_is_linear(struct key_def *key_def)
 {
 	if (key_def->part_count > 1) {
-		int prev = key_def->parts[0].fieldno;
-		for (int i = 1; i < key_def->part_count; ++i) {
-			int next = key_def->parts[i].fieldno;
+		u32 prev = key_def->parts[0].fieldno;
+		for (u32 i = 1; i < key_def->part_count; ++i) {
+			u32 next = key_def->parts[i].fieldno;
 			if (next != (prev + 1)) {
 				return false;
 			}
@@ -310,14 +310,14 @@ fold_with_sparse_parts(struct key_def *key_def, struct tuple *tuple, union spars
 
 	memset(parts, 0, sizeof(parts[0]) * key_def->part_count);
 
-	for (int field = 0; field < key_def->max_fieldno; ++field) {
+	for (u32 field = 0; field < key_def->max_fieldno; ++field) {
 		assert(field < tuple->field_count);
 
 		const u8 *data = part_data;
 		u32 len = load_varint32((const void**) &data);
 
-		int part = key_def->cmp_order[field];
-		if (part != -1) {
+		u32 part = key_def->cmp_order[field];
+		if (part != BOX_FIELD_MAX) {
 			if (key_def->parts[part].type == NUM) {
 				if (len != sizeof parts[part].num32) {
 					tnt_raise(IllegalParams, :"key is not u32");
@@ -352,8 +352,8 @@ fold_with_key_parts(struct key_def *key_def, struct key_data *key_data)
 
 	memset(parts, 0, sizeof(parts[0]) * key_def->part_count);
 
-	int part_count = MIN(key_def->part_count, key_data->part_count);
-	for (int part = 0; part < part_count; ++part) {
+	u32 part_count = MIN(key_def->part_count, key_data->part_count);
+	for (u32 part = 0; part < part_count; ++part) {
 		const u8 *data = part_data;
 		u32 len = load_varint32((const void**) &data);
 
@@ -385,14 +385,14 @@ fold_with_dense_offset(struct key_def *key_def, struct tuple *tuple)
 {
 	const u8 *tuple_data = tuple->data;
 
-	for (int field = 0; field < key_def->max_fieldno; ++field) {
+	for (u32 field = 0; field < key_def->max_fieldno; ++field) {
 		assert(field < tuple->field_count);
 
 		const u8 *data = tuple_data;
 		u32 len = load_varint32((const void**) &data);
 
-		int part = key_def->cmp_order[field];
-		if (part != -1) {
+		u32 part = key_def->cmp_order[field];
+		if (part != BOX_FIELD_MAX) {
 			return (u32) (tuple_data - tuple->data);
 		}
 
@@ -410,14 +410,14 @@ fold_with_num32_value(struct key_def *key_def, struct tuple *tuple)
 {
 	const u8 *tuple_data = tuple->data;
 
-	for (int field = 0; field < key_def->max_fieldno; ++field) {
+	for (u32 field = 0; field < key_def->max_fieldno; ++field) {
 		assert(field < tuple->field_count);
 
 		const u8 *data = tuple_data;
 		u32 len = load_varint32((const void**) &data);
 
-		int part = key_def->cmp_order[field];
-		if (part != -1) {
+		u32 part = key_def->cmp_order[field];
+		if (part != BOX_FIELD_MAX) {
 			u32 value;
 			assert(len == sizeof value);
 			memcpy(&value, data, sizeof value);
@@ -481,7 +481,7 @@ sparse_node_compare(struct key_def *key_def,
 		    struct tuple *tuple_b,
 		    const union sparse_part* parts_b)
 {
-	for (int part = 0; part < key_def->part_count; ++part) {
+	for (u32 part = 0; part < key_def->part_count; ++part) {
 		int r = sparse_part_compare(key_def->parts[part].type,
 					    tuple_a->data, parts_a[part],
 					    tuple_b->data, parts_b[part]);
@@ -501,8 +501,8 @@ sparse_key_node_compare(struct key_def *key_def,
 			struct tuple *tuple,
 			const union sparse_part* parts)
 {
-	int part_count = MIN(key_def->part_count, key_data->part_count);
-	for (int part = 0; part < part_count; ++part) {
+	u32 part_count = MIN(key_def->part_count, key_data->part_count);
+	for (u32 part = 0; part < part_count; ++part) {
 		int r = sparse_part_compare(key_def->parts[part].type,
 					    key_data->data,
 					    key_data->parts[part],
@@ -551,7 +551,7 @@ dense_node_compare(struct key_def *key_def, u32 first_field,
 		   struct tuple *tuple_a, u32 offset_a,
 		   struct tuple *tuple_b, u32 offset_b)
 {
-	int part_count = key_def->part_count;
+	u32 part_count = key_def->part_count;
 	assert(first_field + part_count <= tuple_a->field_count);
 	assert(first_field + part_count <= tuple_b->field_count);
 
@@ -565,7 +565,7 @@ dense_node_compare(struct key_def *key_def, u32 first_field,
 	if (part_count > 1) {
 		u8 *ad = tuple_a->data + offset_a;
 		u8 *bd = tuple_b->data + offset_b;
-		for (int i = 1; i < part_count; ++i) {
+		for (u32 i = 1; i < part_count; ++i) {
 			u32 al = load_varint32((const void**) &ad);
 			u32 bl = load_varint32((const void**) &bd);
 			ad += al;
@@ -576,8 +576,8 @@ dense_node_compare(struct key_def *key_def, u32 first_field,
 	}
 
 	/* Compare key parts. */
-	for (int part = 0; part < part_count; ++part) {
-		int field = key_def->parts[part].fieldno;
+	for (u32 part = 0; part < part_count; ++part) {
+		u32 field = key_def->parts[part].fieldno;
 		u8 *ad = tuple_a->data + off_a[field - first_field];
 		u8 *bd = tuple_b->data + off_b[field - first_field];
 		u32 al = load_varint32((void *) &ad);
@@ -600,14 +600,14 @@ linear_node_compare(struct key_def *key_def,
 		    struct tuple *tuple_a, u32 offset_a,
 		    struct tuple *tuple_b, u32 offset_b)
 {
-	int part_count = key_def->part_count;
+	u32 part_count = key_def->part_count;
 	assert(first_field + part_count <= tuple_a->field_count);
 	assert(first_field + part_count <= tuple_b->field_count);
 
 	/* Compare key parts. */
 	const u8 *ad = tuple_a->data + offset_a;
 	const u8 *bd = tuple_b->data + offset_b;
-	for (int part = 0; part < part_count; ++part) {
+	for (u32 part = 0; part < part_count; ++part) {
 		u32 al = load_varint32((const void**) &ad);
 		u32 bl = load_varint32((const void**) &bd);
 		int r = dense_part_compare(key_def->parts[part].type,
@@ -670,7 +670,7 @@ dense_key_node_compare(struct key_def *key_def,
 		       const struct key_data *key_data,
 		       u32 first_field, struct tuple *tuple, u32 offset)
 {
-	int part_count = key_def->part_count;
+	u32 part_count = key_def->part_count;
 	assert(first_field + part_count <= tuple->field_count);
 
 	/* Allocate space for offsets. */
@@ -680,7 +680,7 @@ dense_key_node_compare(struct key_def *key_def,
 	off[0] = offset;
 	if (part_count > 1) {
 		const u8 *data = tuple->data + offset;
-		for (int i = 1; i < part_count; ++i) {
+		for (u32 i = 1; i < part_count; ++i) {
 			u32 len = load_varint32((const void**) &data);
 			data += len;
 			off[i] = data - tuple->data;
@@ -690,8 +690,8 @@ dense_key_node_compare(struct key_def *key_def,
 	/* Compare key parts. */
 	if (part_count > key_data->part_count)
 		part_count = key_data->part_count;
-	for (int part = 0; part < part_count; ++part) {
-		int field = key_def->parts[part].fieldno;
+	for (u32 part = 0; part < part_count; ++part) {
+		u32 field = key_def->parts[part].fieldno;
 		const u8 *bd = tuple->data + off[field - first_field];
 		u32 bl = load_varint32((void *) &bd);
 		int r = dense_key_part_compare(key_def->parts[part].type,
@@ -715,14 +715,14 @@ linear_key_node_compare(struct key_def *key_def,
 			u32 first_field __attribute__((unused)),
 			struct tuple *tuple, u32 offset)
 {
-	int part_count = key_def->part_count;
+	u32 part_count = key_def->part_count;
 	assert(first_field + part_count <= tuple->field_count);
 
 	/* Compare key parts. */
 	if (part_count > key_data->part_count)
 		part_count = key_data->part_count;
 	u8 *bd = tuple->data + offset;
-	for (int part = 0; part < part_count; ++part) {
+	for (u32 part = 0; part < part_count; ++part) {
 		u32 bl = load_varint32((void *) &bd);
 		int r = dense_key_part_compare(key_def->parts[part].type,
 					       key_data->data,
@@ -928,7 +928,7 @@ tree_iterator_gt(struct iterator *iterator)
 	return [self unfold: node];
 }
 
-- (struct tuple *) findByKey: (const void *) key : (int) part_count
+- (struct tuple *) findByKey: (const void *) key : (u32) part_count
 {
 	assert(key_def->is_unique);
 	check_key_parts(key_def, part_count, false);
@@ -1013,7 +1013,7 @@ tree_iterator_gt(struct iterator *iterator)
 
 - (void) initIterator: (struct iterator *) iterator
 	:(enum iterator_type) type
-	:(void *) key :(int) part_count
+	:(void *) key :(u32) part_count
 {
 	struct tree_iterator *it = tree_iterator(iterator);
 
diff --git a/src/box/tuple.h b/src/box/tuple.h
index ec5f815f2cd98ad8f627319d71689e175ea7c1c7..f1dbfd257022e11dcec4b409a0f2a1c1dd8f7399 100644
--- a/src/box/tuple.h
+++ b/src/box/tuple.h
@@ -76,14 +76,14 @@ tuple_ref(struct tuple *tuple, int count);
  * @returns field data if the field exists, or NULL
  */
 void *
-tuple_field(struct tuple *tuple, size_t i);
+tuple_field(struct tuple *tuple, u32 i);
 
 /**
  * Print a tuple in yaml-compatible mode to tbuf:
  * key: { value, value, value }
  */
 void
-tuple_print(struct tbuf *buf, uint8_t field_count, void *f);
+tuple_print(struct tbuf *buf, u32 field_count, void *f);
 
 /** Tuple length when adding to iov. */
 static inline size_t tuple_len(struct tuple *tuple)
diff --git a/src/box/tuple.m b/src/box/tuple.m
index 655e1a4a9aea6c07cf0076d7005ead4857b8b395..05f088c68aecb01c5edc4a3e476e8d75c4e11e81 100644
--- a/src/box/tuple.m
+++ b/src/box/tuple.m
@@ -90,7 +90,7 @@ next_field(const void *f)
  * @returns field data if field exists or NULL
  */
 void *
-tuple_field(struct tuple *tuple, size_t i)
+tuple_field(struct tuple *tuple, u32 i)
 {
 	void *field = tuple->data;
 
@@ -136,7 +136,7 @@ print_field(struct tbuf *buf, const void *f)
  * key: { value, value, value }
  */
 void
-tuple_print(struct tbuf *buf, uint8_t field_count, void *f)
+tuple_print(struct tbuf *buf, u32 field_count, void *f)
 {
 	if (field_count == 0) {
 		tbuf_printf(buf, "'': {}");
@@ -147,7 +147,7 @@ tuple_print(struct tbuf *buf, uint8_t field_count, void *f)
 	tbuf_printf(buf, ": {");
 	f = next_field(f);
 
-	for (size_t i = 1; i < field_count; i++, f = next_field(f)) {
+	for (u32 i = 1; i < field_count; i++, f = next_field(f)) {
 		print_field(buf, f);
 		if (likely(i + 1 < field_count))
 			tbuf_printf(buf, ", ");
diff --git a/test/box/lua.result b/test/box/lua.result
index 63e8b90e8db2f51975cb29f6721f354bbba614b7..11224b4d44334b57d5676e3d42d6d65d82ececcc 100644
--- a/test/box/lua.result
+++ b/test/box/lua.result
@@ -453,7 +453,7 @@ lua for k,v in pairs(box.cfg) do print(' - ', k, ': ', v) end
 ...
 lua for k,v in pairs(box.space[0]) do if type(v) ~= 'table' then print(' - ', k, ': ', v) end end
 ---
- - cardinality: -1
+ - cardinality: 0
  - estimated_rows: 0
  - n: 0
  - enabled: true
@@ -501,7 +501,7 @@ lua for k,v in pairs(box.cfg) do print(' - ', k, ': ', v) end
 ...
 lua for k,v in pairs(box.space[0]) do if type(v) ~= 'table' then print(' - ', k, ': ', v) end end
 ---
- - cardinality: -1
+ - cardinality: 0
  - estimated_rows: 0
  - n: 0
  - enabled: true