diff --git a/src/box/tuple_format.c b/src/box/tuple_format.c
index 154535ab13e287abd86e1ea0079d88ddf57e3d26..312c96621fba1c0aa83659d8cb229a960b52e587 100644
--- a/src/box/tuple_format.c
+++ b/src/box/tuple_format.c
@@ -378,7 +378,8 @@ tuple_format_use_key_part(struct tuple_format *format, uint32_t field_count,
 	 * i.e. DEFAULT.
 	 */
 	if (field->nullable_action == ON_CONFLICT_ACTION_DEFAULT) {
-		if (part->nullable_action != ON_CONFLICT_ACTION_NONE)
+		if (part->nullable_action != ON_CONFLICT_ACTION_NONE ||
+		    part->path != NULL)
 			field->nullable_action = part->nullable_action;
 	} else if (part->nullable_action == ON_CONFLICT_ACTION_DEFAULT) {
 		if (field->nullable_action == ON_CONFLICT_ACTION_NONE)
diff --git a/test/engine/json.result b/test/engine/json.result
index 9f0c896844cce2cc12c14828d68aff6dfb385f13..2175266fccf47119c53f0772ed0bc3df460095a0 100644
--- a/test/engine/json.result
+++ b/test/engine/json.result
@@ -801,3 +801,43 @@ s.index.sk:select()
 s:drop()
 ---
 ...
+--
+-- gh-4520: Nullable fields in JSON index are not working with a
+--          space having a format defined.
+--
+s = box.schema.space.create('x', {engine = engine})
+---
+...
+pk = s:create_index('pk')
+---
+...
+_ = s:create_index( '_rawdata', { type='tree', unique=false, parts={{ 5, 'scalar', path='pay_date_to', is_nullable=true }} } )
+---
+...
+_ = s:insert{6, 1569246252, 2, 77, { f1 = 123, pay_date_to = box.NULL }, 21, 1, 361 }
+---
+...
+s:format({{type='any', name='1'}, {type='any', name='2'}, {type='any', name='3'}, {type='any', name='4'}, {type='map', name='_rawdata', is_nullable=true}})
+---
+...
+s:drop()
+---
+...
+s = box.schema.space.create('sp', {engine = engine, format = {{type='string', name='key'}, {type='map', name='value', is_nullable=true}}})
+---
+...
+_ = s:create_index('pk', {parts = {'key'}})
+---
+...
+_ = s:create_index('clid', {parts = {{'value.clid', 'str', is_nullable = true}}})
+---
+...
+_ = s:insert({'01', {clid = 'AA', cltp = 20}})
+---
+...
+_ = s:insert({'02', {cltp = 'BB'}})
+---
+...
+s:drop()
+---
+...
diff --git a/test/engine/json.test.lua b/test/engine/json.test.lua
index c6c207dc9bf75fc36bac4621b5d6722f2bf6a9db..4771c3162a861f58df3e6625697a52b9acf54e34 100644
--- a/test/engine/json.test.lua
+++ b/test/engine/json.test.lua
@@ -229,3 +229,21 @@ s:insert{11, {{b = 1}}} -- ok
 s:insert{12, {{a = box.NULL}}} -- ok
 s.index.sk:select()
 s:drop()
+
+--
+-- gh-4520: Nullable fields in JSON index are not working with a
+--          space having a format defined.
+--
+s = box.schema.space.create('x', {engine = engine})
+pk = s:create_index('pk')
+_ = s:create_index( '_rawdata', { type='tree', unique=false, parts={{ 5, 'scalar', path='pay_date_to', is_nullable=true }} } )
+_ = s:insert{6, 1569246252, 2, 77, { f1 = 123, pay_date_to = box.NULL }, 21, 1, 361 }
+s:format({{type='any', name='1'}, {type='any', name='2'}, {type='any', name='3'}, {type='any', name='4'}, {type='map', name='_rawdata', is_nullable=true}})
+s:drop()
+
+s = box.schema.space.create('sp', {engine = engine, format = {{type='string', name='key'}, {type='map', name='value', is_nullable=true}}})
+_ = s:create_index('pk', {parts = {'key'}})
+_ = s:create_index('clid', {parts = {{'value.clid', 'str', is_nullable = true}}})
+_ = s:insert({'01', {clid = 'AA', cltp = 20}})
+_ = s:insert({'02', {cltp = 'BB'}})
+s:drop()