diff --git a/mysql-test/suite/rpl/r/rpl_circular_semi_sync.result b/mysql-test/suite/rpl/r/rpl_circular_semi_sync.result
new file mode 100644
index 0000000000000000000000000000000000000000..dcced9833ca25c7ec191131535a92260d256f358
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_circular_semi_sync.result
@@ -0,0 +1,76 @@
+include/master-slave.inc
+[connection master]
+# Master server_1 and Slave server_2 initialiation ...
+connection server_2;
+include/stop_slave.inc
+connection server_1;
+set @@sql_log_bin = off;
+call mtr.add_suppression("Slave: An attempt was made to binlog GTID 10-1-1 which would create an out-of-order sequence number with existing GTID");
+set @@sql_log_bin = on;
+RESET MASTER;
+set @@session.gtid_domain_id=10;
+set @@global.rpl_semi_sync_master_enabled = 1;
+set @@global.rpl_semi_sync_master_wait_point=AFTER_SYNC;
+connection server_2;
+RESET MASTER;
+ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
+set @@session.gtid_domain_id=20;
+set @@global.rpl_semi_sync_slave_enabled = 1;
+# a 1948 warning is expected
+set @@global.gtid_slave_pos = "";
+Warnings:
+Warning	1948	Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-1. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos
+CHANGE MASTER TO master_use_gtid= slave_pos;
+include/start_slave.inc
+# ... server_1 -> server_2 is set up
+connection server_1;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=Innodb;
+INSERT INTO t1 VALUES (1);
+connection server_2;
+# Circular configuration server_2 -> server_1 initialiation ...
+connection server_1;
+# A. ... first when server_1 is in gtid strict mode...
+set @@global.gtid_strict_mode = true;
+set @@global.rpl_semi_sync_slave_enabled = 1;
+CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_2, master_user='root', master_use_gtid=SLAVE_POS;
+# ...  only for it to fail 'cos if its inconsistent (empty) slave's gtid state:
+SELECT @@global.gtid_slave_pos;
+@@global.gtid_slave_pos
+
+START SLAVE;
+include/wait_for_slave_sql_error.inc [errno=1950]
+# B. ... Resume on the circular setup with the server_id now in the non-strict mode ...
+set @@global.gtid_strict_mode = false;
+include/start_slave.inc
+# ... to have succeeded.
+connection server_2;
+INSERT INTO t1 VALUES (2);
+connection server_1;
+INSERT INTO t1 VALUES (3);
+connection server_2;
+# The gtid states on server_2 must be equal to ...
+SHOW VARIABLES LIKE 'gtid_binlog_pos';
+Variable_name	Value
+gtid_binlog_pos	0-2-1,10-1-3,20-2-1
+SHOW VARIABLES LIKE 'gtid_slave_pos';
+Variable_name	Value
+gtid_slave_pos	0-2-1,10-1-3,20-2-1
+connection server_1;
+# ... the gtid states on server_1
+SHOW VARIABLES LIKE 'gtid_slave_pos';
+Variable_name	Value
+gtid_slave_pos	0-2-1,10-1-3,20-2-1
+SHOW VARIABLES LIKE 'gtid_binlog_pos';
+Variable_name	Value
+gtid_binlog_pos	0-2-1,10-1-3,20-2-1
+# Cleanup
+connection server_1;
+include/stop_slave.inc
+set @@global.rpl_semi_sync_master_enabled = default;
+set @@global.rpl_semi_sync_slave_enabled = default;
+set @@global.rpl_semi_sync_master_wait_point=default;
+DROP TABLE t1;
+connection server_2;
+set @@global.rpl_semi_sync_master_enabled = default;
+set @@global.rpl_semi_sync_slave_enabled = default;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_circular_semi_sync.cnf b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.cnf
new file mode 100644
index 0000000000000000000000000000000000000000..be39fea91d81c380a9681f39d41f6ece591b8cb2
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.cnf
@@ -0,0 +1,11 @@
+!include suite/rpl/rpl_1slave_base.cnf
+!include include/default_client.cnf
+
+
+[mysqld.1]
+log-slave-updates
+sync-binlog=1
+
+[mysqld.2]
+log-slave-updates
+sync-binlog=1
diff --git a/mysql-test/suite/rpl/t/rpl_circular_semi_sync.test b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.test
new file mode 100644
index 0000000000000000000000000000000000000000..51fa5a242ea5e771a16871b407a8746eda9db18c
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.test
@@ -0,0 +1,115 @@
+# ==== References ====
+#
+# MDEV-27760 event may non stop replicate in circular semisync setup
+#
+--source include/have_innodb.inc
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+
+# The following tests prove
+# A. out-of-order gtid error when the stict gtid mode semisync slave
+#    receives the same server-id gtid event inconsistent
+#    (rpl_semi_sync_fail_over tests the consistent case) with its state;
+# B. in the non-strict mode the same server-id events remains ignored
+#    by default as usual.
+#
+--echo # Master server_1 and Slave server_2 initialiation ...
+--connection server_2
+--source include/stop_slave.inc
+
+# Initial master
+--connection server_1
+set @@sql_log_bin = off;
+call mtr.add_suppression("Slave: An attempt was made to binlog GTID 10-1-1 which would create an out-of-order sequence number with existing GTID");
+set @@sql_log_bin = on;
+
+RESET MASTER;
+
+set @@session.gtid_domain_id=10;
+
+set @@global.rpl_semi_sync_master_enabled = 1;
+set @@global.rpl_semi_sync_master_wait_point=AFTER_SYNC;
+
+--connection server_2
+RESET MASTER;
+ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
+
+set @@session.gtid_domain_id=20;
+
+set @@global.rpl_semi_sync_slave_enabled = 1;
+--echo # a 1948 warning is expected
+set @@global.gtid_slave_pos = "";
+CHANGE MASTER TO master_use_gtid= slave_pos;
+--source include/start_slave.inc
+--echo # ... server_1 -> server_2 is set up
+
+--connection server_1
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=Innodb;
+INSERT INTO t1 VALUES (1);
+--save_master_pos
+
+--connection server_2
+--sync_with_master
+
+--echo # Circular configuration server_2 -> server_1 initialiation ...
+--connection server_1
+--echo # A. ... first when server_1 is in gtid strict mode...
+set @@global.gtid_strict_mode = true;
+set @@global.rpl_semi_sync_slave_enabled = 1;
+
+evalp CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_2, master_user='root', master_use_gtid=SLAVE_POS;
+
+--echo # ...  only for it to fail 'cos if its inconsistent (empty) slave's gtid state:
+SELECT @@global.gtid_slave_pos;
+START SLAVE;
+#  ER_GTID_STRICT_OUT_OF_ORDER
+--let $slave_sql_errno = 1950
+--source include/wait_for_slave_sql_error.inc
+
+--echo # B. ... Resume on the circular setup with the server_id now in the non-strict mode ...
+set @@global.gtid_strict_mode = false;
+--source include/start_slave.inc
+
+--echo # ... to have succeeded.
+
+--connection server_2
+INSERT INTO t1 VALUES (2);
+--save_master_pos
+
+--connection server_1
+--sync_with_master
+
+INSERT INTO t1 VALUES (3);
+--save_master_pos
+
+--connection server_2
+--sync_with_master
+--echo # The gtid states on server_2 must be equal to ...
+--let $wait_condition=select @@gtid_slave_pos=@@gtid_binlog_pos
+--source include/wait_condition.inc
+SHOW VARIABLES LIKE 'gtid_binlog_pos';
+SHOW VARIABLES LIKE 'gtid_slave_pos';
+
+--connection server_1
+--echo # ... the gtid states on server_1
+--let $wait_condition=select @@gtid_slave_pos=@@gtid_binlog_pos
+--source include/wait_condition.inc
+SHOW VARIABLES LIKE 'gtid_slave_pos';
+SHOW VARIABLES LIKE 'gtid_binlog_pos';
+
+--echo # Cleanup
+--connection server_1
+--source include/stop_slave.inc
+set @@global.rpl_semi_sync_master_enabled = default;
+set @@global.rpl_semi_sync_slave_enabled = default;
+set @@global.rpl_semi_sync_master_wait_point=default;
+
+DROP TABLE t1;
+--save_master_pos
+
+--connection server_2
+--sync_with_master
+set @@global.rpl_semi_sync_master_enabled = default;
+set @@global.rpl_semi_sync_slave_enabled = default;
+
+--source include/rpl_end.inc
diff --git a/sql/slave.cc b/sql/slave.cc
index c0eef02ca7a8a18442cf202f95ca6b7c7d326312..a6578be199adc5dd323c0ba7603ee669f66d600f 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -6186,13 +6186,13 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
   bool is_rows_event= false;
   /*
     The flag has replicate_same_server_id semantics and is raised to accept
-    a same-server-id event on the semisync slave, for both the gtid and legacy
-    connection modes.
-    Such events can appear as result of this server recovery so the event
-    was created there and replicated elsewhere right before the crash. At recovery
-    it could be evicted from the server's binlog.
-  */
-  bool do_accept_own_server_id= false;
+    a same-server-id event group by the gtid strict mode semisync slave.
+    Own server-id events can appear as result of this server crash-recovery:
+    the transaction was created on this server then being master, got replicated
+    elsewhere right before the crash before commit;
+    finally at recovery the transaction gets evicted from the server's binlog.
+ */
+  bool do_accept_own_server_id;
   /*
     FD_q must have been prepared for the first R_a event
     inside get_master_version_and_clock()
@@ -6281,6 +6281,8 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
                     dbug_rows_event_count = 0;
                   };);
 #endif
+  s_id= uint4korr(buf + SERVER_ID_OFFSET);
+
   mysql_mutex_lock(&mi->data_lock);
 
   switch (buf[EVENT_TYPE_OFFSET]) {
@@ -6722,6 +6724,7 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
 
     ++mi->events_queued_since_last_gtid;
     inc_pos= event_len;
+
   }
   break;
   /*
@@ -6864,6 +6867,10 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
     break;
   }
 
+  do_accept_own_server_id= (s_id == global_system_variables.server_id
+    && rpl_semi_sync_slave_enabled && opt_gtid_strict_mode
+    && mi->using_gtid != Master_info::USE_GTID_NO);
+
   /*
     Integrity of Rows- event group check.
     A sequence of Rows- events must end with STMT_END_F flagged one.
@@ -6909,7 +6916,6 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
   */
 
   mysql_mutex_lock(log_lock);
-  s_id= uint4korr(buf + SERVER_ID_OFFSET);
   /*
     Write the event to the relay log, unless we reconnected in the middle
     of an event group and now need to skip the initial part of the group that
@@ -6955,7 +6961,7 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
   else
   if ((s_id == global_system_variables.server_id &&
        !(mi->rli.replicate_same_server_id ||
-         (do_accept_own_server_id= rpl_semi_sync_slave_enabled))) ||
+         do_accept_own_server_id)) ||
       event_that_should_be_ignored(buf) ||
       /*
         the following conjunction deals with IGNORE_SERVER_IDS, if set