diff --git a/src/box/alter.cc b/src/box/alter.cc
index c02531e87960c23b25dea7a8d2ff0bdf7faa41c7..2e70333a1db5fb5c9d1199a2a571e388d7864a65 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -1635,8 +1635,22 @@ on_commit_dd_cluster(struct trigger *trigger, void *event)
 	(void) trigger;
 	struct txn_stmt *stmt = txn_stmt((struct txn *) event);
 	struct tuple *new_tuple = stmt->new_tuple;
+
+	if (new_tuple == NULL) {
+		uint32_t old_id = tuple_field_u32(stmt->old_tuple, 0);
+		cluster_del_server(old_id);
+		return;
+	}
 	uint32_t id = tuple_field_u32(new_tuple, 0);
 	tt_uuid uuid = tuple_field_uuid(new_tuple, 1);
+	struct tuple *old_tuple = stmt->old_tuple;
+	if (old_tuple != NULL) {
+		uint32_t old_id = tuple_field_u32(old_tuple, 0);
+		if (id != old_id) {
+			/* box.space._cluster:update(old, {{'=', 1, new}} */
+			cluster_del_server(old_id);
+		}
+	}
 
 	cluster_set_server(&uuid, id);
 }
@@ -1670,8 +1684,10 @@ on_replace_dd_cluster(struct trigger *trigger, void *event)
 	txn_check_autocommit(txn, "Space _cluster");
 	struct txn_stmt *stmt = txn_stmt(txn);
 	struct tuple *new_tuple = stmt->new_tuple;
-	if (new_tuple == NULL)
-		tnt_raise(ClientError, ER_SERVER_ID_IS_RO);
+	if (new_tuple == NULL) {
+		trigger_add(&txn->on_commit, &commit_cluster_trigger);
+		return;
+	}
 
 	/* Check fields */
 	uint32_t server_id = tuple_field_u32(new_tuple, 0);
@@ -1682,14 +1698,6 @@ on_replace_dd_cluster(struct trigger *trigger, void *event)
 	if (tt_uuid_is_nil(&server_uuid))
 		tnt_raise(ClientError, ER_INVALID_UUID,
 			  tt_uuid_str(&server_uuid));
-	struct tuple *old_tuple = stmt->old_tuple;
-	if (old_tuple != NULL) {
-		/* server_id is read-only, other fields can be changed */
-		uint32_t old_server_id = tuple_field_u32(old_tuple, 0);
-		if (server_id != old_server_id)
-			tnt_raise(ClientError, ER_SERVER_ID_IS_RO,
-				  (unsigned) server_id);
-	}
 
 	trigger_add(&txn->on_commit, &commit_cluster_trigger);
 }
diff --git a/src/box/cluster.cc b/src/box/cluster.cc
index 356f49ff313f4fa86dfe74d4322b4fbe4edf9c21..031ecff6a681226a6b34d9a7a5087fd710f22cd2 100644
--- a/src/box/cluster.cc
+++ b/src/box/cluster.cc
@@ -69,3 +69,14 @@ cluster_set_server(const tt_uuid *server_uuid, uint32_t server_id)
 		box_set_ro(false);
 	}
 }
+
+void
+cluster_del_server(uint32_t server_id)
+{
+	struct recovery_state *r = recovery;
+	vclock_del_server(&r->vclock, server_id);
+	if (r->server_id == server_id) {
+		r->server_id = 0;
+		box_set_ro(true);
+	}
+}
diff --git a/src/box/cluster.h b/src/box/cluster.h
index b98e2ef1b1d2e3d623c65bce6aa17553854c0160..15ce75f038a1e819822a62275ac2f5ceb6ab220a 100644
--- a/src/box/cluster.h
+++ b/src/box/cluster.h
@@ -105,6 +105,9 @@ cserver_id_is_reserved(uint32_t id)
 void
 cluster_set_server(const tt_uuid *server_uuid, uint32_t id);
 
+void
+cluster_del_server(uint32_t server_id);
+
 /** }}} **/
 
 #endif
diff --git a/src/errcode.h b/src/errcode.h
index 41436381a39e11f5cbbf1b8ed3aa02bbef6cd61f..3c1b8fd6b5533065e80d98b6734aa0bf33e1c962 100644
--- a/src/errcode.h
+++ b/src/errcode.h
@@ -115,7 +115,7 @@ enum { TNT_ERRMSG_MAX = 512 };
 	/* 63 */_(ER_CLUSTER_ID_MISMATCH,	2, "Cluster id of the replica %s doesn't match cluster id of the master %s") \
 	/* 64 */_(ER_INVALID_UUID,		2, "Invalid UUID: %s") \
 	/* 65 */_(ER_CLUSTER_ID_IS_RO,		2, "Can't reset cluster id: it is already assigned") \
-	/* 66 */_(ER_SERVER_ID_IS_RO,		2, "Can't reset server id") \
+	/* 66 */_(ER_RESERVED66,		2, "Reserved66") \
 	/* 67 */_(ER_SERVER_ID_IS_RESERVED,	2, "Can't initialize server id with a reserved value %u") \
 	/* 68 */_(ER_INVALID_ORDER,		2, "Invalid LSN order for server %u: previous LSN = %llu, new lsn = %llu") \
 	/* 69 */_(ER_MISSING_REQUEST_FIELD,	2, "Missing mandatory field '%s' in request") \
diff --git a/test/box/misc.result b/test/box/misc.result
index 5a65842d9dcf5f3287cc162a0fe7840e3e94167c..b58402743425ee14bad1524e63dee097f671a491 100644
--- a/test/box/misc.result
+++ b/test/box/misc.result
@@ -197,7 +197,6 @@ t;
   - 'box.error.NO_SUCH_FUNCTION : 51'
   - 'box.error.TUPLE_NOT_FOUND : 4'
   - 'box.error.DROP_USER : 44'
-  - 'box.error.SERVER_ID_IS_RO : 66'
   - 'box.error.CROSS_ENGINE_TRANSACTION : 81'
   - 'box.error.MODIFY_INDEX : 14'
   - 'box.error.PASSWORD_MISMATCH : 47'
diff --git a/test/replication/cluster.result b/test/replication/cluster.result
index efd3543df86a852b77e870b0f8e630b23e4610df..8be88a719587137e3452a009ac329aa811736783 100644
--- a/test/replication/cluster.result
+++ b/test/replication/cluster.result
@@ -1,3 +1,6 @@
+-------------------------------------------------------------
+gh-434: Assertion if replace _cluster tuple
+-------------------------------------------------------------
 box.space._cluster:replace{1, '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae'}
 ---
 - [1, '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae']
@@ -22,15 +25,109 @@ box.info.server.uuid
 ---
 - 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae
 ...
-box.space._cluster:delete(1)
+box.space._cluster:replace{1, require('uuid').NULL:str()}
 ---
-- error: Can't reset server id
+- error: 'Invalid UUID: 00000000-0000-0000-0000-000000000000'
 ...
-box.space._cluster:update(1, {{'=', 1, 10}})
+-------------------------------------------------------------
+gh-527: update vclock on delete from box.space._cluster
+-------------------------------------------------------------
+box.schema.user.grant('guest', 'read,write,execute', 'universe')
 ---
-- error: Can't reset server id
 ...
-box.space._cluster:replace{1, require('uuid').NULL:str()}
+box.space._schema:insert{"test", 48}
 ---
-- error: 'Invalid UUID: 00000000-0000-0000-0000-000000000000'
+- ['test', 48]
+...
+box.info.server.id
+---
+- 2
+...
+box.info.server.ro
+---
+- false
+...
+box.info.server.lsn
+---
+- 1
+...
+box.info.vclock[2]
+---
+- 1
+...
+box.space._cluster:delete{2}
+---
+- [2, '<replica uuid>']
+...
+box.info.server.id
+---
+- 0
+...
+box.info.server.ro
+---
+- true
+...
+box.info.server.lsn
+---
+- -1
+...
+box.info.vclock[2]
+---
+- null
+...
+box.space._schema:replace{"test", 48}
+---
+- error: Can't modify data because this server in read-only mode.
+...
+box.space._cluster:insert{10, "<replica uuid>"}
+---
+- [10, '<replica uuid>']
+...
+box.info.server.id
+---
+- 10
+...
+box.info.server.ro
+---
+- false
+...
+box.info.server.lsn
+---
+- 0
+...
+box.info.vclock[2]
+---
+- null
+...
+box.info.vclock[10]
+---
+- 0
+...
+box.space._cluster:update(10, {{'=', 1, 11}})
+---
+- [11, '<replica uuid>']
+...
+box.info.server.id
+---
+- 11
+...
+box.info.server.ro
+---
+- false
+...
+box.info.server.lsn
+---
+- 0
+...
+box.info.vclock[2]
+---
+- null
+...
+box.info.vclock[10]
+---
+- null
+...
+box.info.vclock[11]
+---
+- 0
 ...
diff --git a/test/replication/cluster.test.py b/test/replication/cluster.test.py
index b909a00082b2c665a038f96b30b6f7ccf375214a..b8b902da4dc662dbbaa09c4aee1e00105a85b85c 100644
--- a/test/replication/cluster.test.py
+++ b/test/replication/cluster.test.py
@@ -1,9 +1,12 @@
+import os
+import sys
 import re
 import yaml
+from lib.tarantool_server import TarantoolServer
 
-#
-# gh-434: Assertion if replace _cluster tuple
-#
+print '-------------------------------------------------------------'
+print 'gh-434: Assertion if replace _cluster tuple'
+print '-------------------------------------------------------------'
 
 new_uuid = '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae'
 
@@ -36,13 +39,71 @@ server.restart()
 
 server.admin("box.info.server.uuid")
 
-# Can't reset server id
-server.admin("box.space._cluster:delete(1)")
-server.admin("box.space._cluster:update(1, {{'=', 1, 10}})")
-
 # Invalid UUID
 server.admin("box.space._cluster:replace{1, require('uuid').NULL:str()}")
 
 # Cleanup
 server.stop()
 server.deploy()
+
+print '-------------------------------------------------------------'
+print 'gh-527: update vclock on delete from box.space._cluster'
+print '-------------------------------------------------------------'
+
+# master server
+master = server
+master_id = master.get_param('server')['id']
+
+master.admin("box.schema.user.grant('guest', 'read,write,execute', 'universe')")
+
+replica = TarantoolServer(server.ini)
+replica.script = 'replication/replica.lua'
+replica.vardir = os.path.join(server.vardir, 'replica')
+replica.rpl_master = master
+replica.deploy()
+replica.wait_lsn(master_id, master.get_lsn(master_id))
+replica_id = replica.get_param('server')['id']
+replica_uuid = replica.get_param('server')['uuid']
+sys.stdout.push_filter(replica_uuid, '<replica uuid>')
+replica.admin('box.space._schema:insert{"test", 48}')
+
+replica.admin('box.info.server.id')
+replica.admin('box.info.server.ro')
+replica.admin('box.info.server.lsn') # 1
+replica.admin('box.info.vclock[%d]' % replica_id)
+
+master.admin('box.space._cluster:delete{%d}' % replica_id)
+replica.wait_lsn(master_id, master.get_lsn(master_id))
+replica.admin('box.info.server.id')
+replica.admin('box.info.server.ro')
+replica.admin('box.info.server.lsn') # -1
+replica.admin('box.info.vclock[%d]' % replica_id)
+# replica is read-only
+replica.admin('box.space._schema:replace{"test", 48}')
+
+replica_id2 = 10
+master.admin('box.space._cluster:insert{%d, "%s"}' %
+    (replica_id2, replica_uuid))
+replica.wait_lsn(master_id, master.get_lsn(master_id))
+replica.admin('box.info.server.id')
+replica.admin('box.info.server.ro')
+replica.admin('box.info.server.lsn') # 0
+replica.admin('box.info.vclock[%d]' % replica_id)
+replica.admin('box.info.vclock[%d]' % replica_id2)
+
+replica_id3 = 11
+server.admin("box.space._cluster:update(%d, {{'=', 1, %d}})" %
+    (replica_id2, replica_id3))
+replica.wait_lsn(master_id, master.get_lsn(master_id))
+replica.admin('box.info.server.id')
+replica.admin('box.info.server.ro')
+replica.admin('box.info.server.lsn') # 0
+replica.admin('box.info.vclock[%d]' % replica_id)
+replica.admin('box.info.vclock[%d]' % replica_id2)
+replica.admin('box.info.vclock[%d]' % replica_id3)
+
+sys.stdout.pop_filter()
+
+# Cleanup
+server.stop()
+server.deploy()