diff --git a/README.FreeBSD b/README.FreeBSD
index 3908d13eceac99a9ab5f66ee5bb5a4abf9f68e45..ca643279f2087033ebf9f3a0ace311973065c6c7 100644
--- a/README.FreeBSD
+++ b/README.FreeBSD
@@ -1,8 +1,8 @@
-Target OS: FreeBSD 10.1 (RELEASE)
+Target OS: FreeBSD 10.4 (RELEASE) and FreeBSD 11.2 (RELEASE)
 
 1. Install necessary packages:
 -------------
-pkg install sudo git cmake gmake readline
+pkg install git cmake gmake readline icu
 
 
 2. Download & build tarantool source code:
@@ -19,11 +19,14 @@ gmake
 3. Set up python 2.7
 -------------
 
-From packages:
-pkg install python27 py27-yaml py27-daemon py27-msgpack
+Install testing dependences either from packages or from pip.
 
-From pip:
+3.1. From packages:
+-------------
+pkg install python27 py27-yaml py27-daemon py27-msgpack
 
+3.2. From pip:
+-------------
 pkg install py27-virtualenv
 virtualenv .venv
 source .venv/bin/activate
diff --git a/cmake/FindCURL.cmake b/cmake/FindCURL.cmake
index e2e2c6f201b74eefc3a73298b2af22d3f35e17e2..e13b6cde437f64a7d1e1906dba1e607eaa210012 100644
--- a/cmake/FindCURL.cmake
+++ b/cmake/FindCURL.cmake
@@ -24,9 +24,15 @@ else()
     set(NGHTTP2_LIB_NAME nghttp2)
 endif()
 
-# Curl may require nghttp library, search for it and add to dependicies if
-# found
+# Always links pthread and dl dynamically.
+set(PTHREAD_LIB_NAME pthread)
+set(DL_LIB_NAME dl)
+
+# Curl may be linked with optional or target-dependent libraries,
+# search for them and add to dependicies if found.
 find_library(NGHTTP2_LIBRARY NAMES ${NGHTTP2_LIB_NAME})
+find_library(PTHREAD_LIBRARY NAMES ${PTHREAD_LIB_NAME})
+find_library(DL_LIBRARY NAMES ${DL_LIB_NAME})
 
 if(DEFINED CURL_ROOT)
     set(CURL_FIND_OPTS NO_CMAKE NO_CMAKE_SYSTEM_PATH)
@@ -79,14 +85,21 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(CURL
 
 if(CURL_FOUND)
   set(CURL_LIBRARIES ${CURL_LIBRARY})
+  set(CURL_LIBRARIES ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES})
   if(BUILD_STATIC)
-    # in case of a static build we have to add curl dependencies
+    # In case of a static build we have to add curl dependencies.
     if(NOT "${NGHTTP2_LIBRARY}" STREQUAL "NGHTTP2_LIBRARY-NOTFOUND")
       set(CURL_LIBRARIES ${CURL_LIBRARIES} ${NGHTTP2_LIBRARY})
     endif()
+    if(NOT "${PTHREAD_LIBRARY}" STREQUAL "PTHREAD_LIBRARY-NOTFOUND")
+      set(CURL_LIBRARIES ${CURL_LIBRARIES} ${PTHREAD_LIBRARY})
+    endif()
+    if(NOT "${DL_LIBRARY}" STREQUAL "DL_LIBRARY-NOTFOUND")
+      set(CURL_LIBRARIES ${CURL_LIBRARIES} ${DL_LIBRARY})
+    endif()
   endif()
   set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR})
-  set(CMAKE_REQUIRED_LIBRARIES ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} pthread dl)
+  set(CMAKE_REQUIRED_LIBRARIES ${CURL_LIBRARIES})
   set(CMAKE_REQUIRED_INCLUDES ${CURL_INCLUDE_DIRS})
   check_c_source_runs("
     #include <curl/curl.h>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d296348a33d4ad80a92f7f3dfc56f9f369fcf3b4..ceff96ec0b1d9a12b5dffee5c8cb7265c8ae49ba 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -67,7 +67,14 @@ add_custom_target(ragel
     WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
     COMMAND ragel -G2 src/uri.rl -o src/uri.c)
 
-set (generic_libraries pthread dl)
+# There is no libdl.so on FreeBSD prior to 11.2.
+#
+# Always links pthread and dl dynamically.
+set(generic_libraries pthread)
+find_library(DL_LIBRARY NAMES dl)
+if(NOT "${DL_LIBRARY}" STREQUAL "DL_LIBRARY-NOTFOUND")
+    set(generic_libraries ${generic_libraries} dl)
+endif()
 
 set (core_sources
      diag.c
diff --git a/src/box/tuple_format.c b/src/box/tuple_format.c
index 1c4b2e6a4e8fa125e1e662dedfbee89b15ff8873..cf61283d2783b3eb02a98ca97974d0b4f030503f 100644
--- a/src/box/tuple_format.c
+++ b/src/box/tuple_format.c
@@ -38,7 +38,7 @@ static intptr_t recycled_format_ids = FORMAT_ID_NIL;
 static uint32_t formats_size = 0, formats_capacity = 0;
 
 static const struct tuple_field tuple_field_default = {
-	FIELD_TYPE_ANY, TUPLE_OFFSET_SLOT_NIL, false, false,
+	FIELD_TYPE_ANY, TUPLE_OFFSET_SLOT_NIL, false, true,
 };
 
 /**
@@ -81,15 +81,8 @@ tuple_format_create(struct tuple_format *format, struct key_def * const *keys,
 			assert(part->fieldno < format->field_count);
 			struct tuple_field *field =
 				&format->fields[part->fieldno];
-			if (part->fieldno >= field_count) {
-				field->is_nullable = part->is_nullable;
-			} else if (field->is_nullable != part->is_nullable) {
-				/*
-				 * In case of mismatch set the most
-				 * strict option for is_nullable.
-				 */
-				field->is_nullable = false;
-			}
+			field->is_nullable = field->is_nullable &&
+					     part->is_nullable;
 
 			/*
 			 * Check that there are no conflicts
diff --git a/src/say.c b/src/say.c
index 7f018ec11f0fc65caec93f99dec6dd90a18bba79..860176ac21857523c6c1fbf17827c27ee5f2f092 100644
--- a/src/say.c
+++ b/src/say.c
@@ -37,6 +37,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <netdb.h>
+#include <netinet/in.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <fcntl.h>
diff --git a/test/engine/null.result b/test/engine/null.result
index 48d678443be4d3d43dd52f656ac422acb7f69e34..4ec0142493b141279bfc784a3699f0e807a68844 100644
--- a/test/engine/null.result
+++ b/test/engine/null.result
@@ -1693,3 +1693,27 @@ s:insert{9, 10} -- Success.
 s:drop()
 ---
 ...
+-- gh-3744: Assertion after improper index creation
+s = box.schema.space.create('test', {engine=engine})
+---
+...
+pk = s:create_index('primary', {parts={1, 'unsigned'}})
+---
+...
+sk1 = s:create_index('sk1', {parts={{2, 'number', is_nullable=false}}})
+---
+...
+s:insert{1, -1, 1}
+---
+- [1, -1, 1]
+...
+sk2 = s:create_index('sk2', {parts={{2, 'number', is_nullable=true}}})
+---
+...
+s:insert{2, nil, 2} --error
+---
+- error: 'Tuple field 2 type does not match one required by operation: expected number'
+...
+s:drop()
+---
+...
diff --git a/test/engine/null.test.lua b/test/engine/null.test.lua
index 5eb068499908e0a580fb98207a0f3e11abc3437b..ba13adf47db31fe333ea6ec18fbb48ccd292471a 100644
--- a/test/engine/null.test.lua
+++ b/test/engine/null.test.lua
@@ -505,3 +505,12 @@ s:insert{5} -- Fail.
 s:insert{9, 10} -- Success.
 
 s:drop()
+
+-- gh-3744: Assertion after improper index creation
+s = box.schema.space.create('test', {engine=engine})
+pk = s:create_index('primary', {parts={1, 'unsigned'}})
+sk1 = s:create_index('sk1', {parts={{2, 'number', is_nullable=false}}})
+s:insert{1, -1, 1}
+sk2 = s:create_index('sk2', {parts={{2, 'number', is_nullable=true}}})
+s:insert{2, nil, 2} --error
+s:drop()