diff --git a/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result b/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result
index 0e066fc0418..5771b0f405f 100644
--- a/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result
+++ b/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result
@@ -555,6 +555,62 @@ a
 32
 33
 34
+*** MDEV-31723: Crash on SET SESSION gtid_seq_no= DEFAULT
+connection server_1;
+SET SESSION gtid_seq_no= 2000;
+SELECT @@SESSION.gtid_seq_no;
+@@SESSION.gtid_seq_no
+2000
+INSERT INTO t1 VALUES (40);
+SELECT @@SESSION.gtid_seq_no;
+@@SESSION.gtid_seq_no
+0
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2000
+INSERT INTO t1 VALUES (41);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2001
+SET SESSION gtid_seq_no= 2010;
+INSERT INTO t1 VALUES (42);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2010
+SET @old_strict= @@GLOBAL.gtid_strict_mode;
+SET GLOBAL gtid_strict_mode= 1;
+SET SESSION gtid_seq_no= 0;
+INSERT INTO t1 VALUES (43);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2011
+SET GLOBAL gtid_strict_mode= @old_strict;
+INSERT INTO t1 VALUES (44);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2012
+SET SESSION gtid_seq_no= 2020;
+SET SESSION gtid_seq_no= 2030;
+INSERT INTO t1 VALUES (45);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2030
+SET SESSION gtid_seq_no= 2040;
+SET SESSION gtid_seq_no= DEFAULT;
+INSERT INTO t1 VALUES (46);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2031
+INSERT INTO t1 VALUES (47);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2032
+SET SESSION gtid_seq_no= 2050;
+SET SESSION gtid_seq_no= 0;
+INSERT INTO t1 VALUES (48);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2033
 connection server_1;
 DROP TABLE t1;
 include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_gtid_basic.result b/mysql-test/suite/rpl/r/rpl_gtid_basic.result
index 32df09789cc..aefb80a7c13 100644
--- a/mysql-test/suite/rpl/r/rpl_gtid_basic.result
+++ b/mysql-test/suite/rpl/r/rpl_gtid_basic.result
@@ -554,6 +554,62 @@ a
 32
 33
 34
+*** MDEV-31723: Crash on SET SESSION gtid_seq_no= DEFAULT
+connection server_1;
+SET SESSION gtid_seq_no= 2000;
+SELECT @@SESSION.gtid_seq_no;
+@@SESSION.gtid_seq_no
+2000
+INSERT INTO t1 VALUES (40);
+SELECT @@SESSION.gtid_seq_no;
+@@SESSION.gtid_seq_no
+0
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2000
+INSERT INTO t1 VALUES (41);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2001
+SET SESSION gtid_seq_no= 2010;
+INSERT INTO t1 VALUES (42);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2010
+SET @old_strict= @@GLOBAL.gtid_strict_mode;
+SET GLOBAL gtid_strict_mode= 1;
+SET SESSION gtid_seq_no= 0;
+INSERT INTO t1 VALUES (43);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2011
+SET GLOBAL gtid_strict_mode= @old_strict;
+INSERT INTO t1 VALUES (44);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2012
+SET SESSION gtid_seq_no= 2020;
+SET SESSION gtid_seq_no= 2030;
+INSERT INTO t1 VALUES (45);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2030
+SET SESSION gtid_seq_no= 2040;
+SET SESSION gtid_seq_no= DEFAULT;
+INSERT INTO t1 VALUES (46);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2031
+INSERT INTO t1 VALUES (47);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2032
+SET SESSION gtid_seq_no= 2050;
+SET SESSION gtid_seq_no= 0;
+INSERT INTO t1 VALUES (48);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+dom0_pos
+0-1-2033
 connection server_1;
 DROP TABLE t1;
 include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_rotate_logs.result b/mysql-test/suite/rpl/r/rpl_rotate_logs.result
index 2518b207111..d720b0b865e 100644
--- a/mysql-test/suite/rpl/r/rpl_rotate_logs.result
+++ b/mysql-test/suite/rpl/r/rpl_rotate_logs.result
@@ -1,5 +1,6 @@
 connect  master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK;
 connect  slave,localhost,root,,test,$SLAVE_MYPORT,$SLAVE_MYSOCK;
+SET GLOBAL gtid_slave_pos= "";
 connection slave;
 CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
 start slave;
diff --git a/mysql-test/suite/rpl/t/rpl_gtid_basic.test b/mysql-test/suite/rpl/t/rpl_gtid_basic.test
index 9cedebcfd38..70bd0087f7a 100644
--- a/mysql-test/suite/rpl/t/rpl_gtid_basic.test
+++ b/mysql-test/suite/rpl/t/rpl_gtid_basic.test
@@ -565,6 +565,50 @@ SELECT * FROM t1 WHERE a >= 30 ORDER BY a;
 SELECT * FROM t1 WHERE a >= 30 ORDER BY a;
 
 
+--echo *** MDEV-31723: Crash on SET SESSION gtid_seq_no= DEFAULT
+--connection server_1
+
+# Setting gtid_seq_no forces the GTID logged, but only once.
+SET SESSION gtid_seq_no= 2000;
+SELECT @@SESSION.gtid_seq_no;
+INSERT INTO t1 VALUES (40);
+SELECT @@SESSION.gtid_seq_no;
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+INSERT INTO t1 VALUES (41);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+
+# Setting to 0 has no effect.
+SET SESSION gtid_seq_no= 2010;
+INSERT INTO t1 VALUES (42);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+SET @old_strict= @@GLOBAL.gtid_strict_mode;
+SET GLOBAL gtid_strict_mode= 1;
+SET SESSION gtid_seq_no= 0;
+INSERT INTO t1 VALUES (43);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+SET GLOBAL gtid_strict_mode= @old_strict;
+INSERT INTO t1 VALUES (44);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+
+# Setting gtid_seq_no multiple times.
+SET SESSION gtid_seq_no= 2020;
+SET SESSION gtid_seq_no= 2030;
+INSERT INTO t1 VALUES (45);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+
+# Setting to DEFAULT or 0 disables prior setting.
+SET SESSION gtid_seq_no= 2040;
+SET SESSION gtid_seq_no= DEFAULT;
+INSERT INTO t1 VALUES (46);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+INSERT INTO t1 VALUES (47);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+SET SESSION gtid_seq_no= 2050;
+SET SESSION gtid_seq_no= 0;
+INSERT INTO t1 VALUES (48);
+SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
+
+
 # Clean up.
 --connection server_1
 DROP TABLE t1;
diff --git a/mysql-test/suite/rpl/t/rpl_rotate_logs.test b/mysql-test/suite/rpl/t/rpl_rotate_logs.test
index 0d65a05bf50..4dd58931cd9 100644
--- a/mysql-test/suite/rpl/t/rpl_rotate_logs.test
+++ b/mysql-test/suite/rpl/t/rpl_rotate_logs.test
@@ -20,6 +20,9 @@
 connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
 connect (slave,localhost,root,,test,$SLAVE_MYPORT,$SLAVE_MYSOCK);
 
+# Reset the GTID position explicitly (since we're not using rpl_init.inc).
+SET GLOBAL gtid_slave_pos= "";
+
 # Create empty file
 let $MYSQLD_SLAVE_DATADIR= `select @@datadir`;
 write_file $MYSQLD_SLAVE_DATADIR/master.info;
diff --git a/mysql-test/suite/sys_vars/r/gtid_seq_no_basic.result b/mysql-test/suite/sys_vars/r/gtid_seq_no_basic.result
index f0aa0d2ba97..855be9de503 100644
--- a/mysql-test/suite/sys_vars/r/gtid_seq_no_basic.result
+++ b/mysql-test/suite/sys_vars/r/gtid_seq_no_basic.result
@@ -8,6 +8,7 @@ SELECT @@session.gtid_seq_no;
 20
 SET GLOBAL gtid_seq_no= DEFAULT;
 ERROR HY000: Variable 'gtid_seq_no' is a SESSION variable and can't be used with SET GLOBAL
+SET SESSION gtid_seq_no= DEFAULT;
 SET SESSION gtid_seq_no= -1;
 Warnings:
 Warning	1292	Truncated incorrect gtid_seq_no value: '-1'
diff --git a/mysql-test/suite/sys_vars/t/gtid_seq_no_basic.test b/mysql-test/suite/sys_vars/t/gtid_seq_no_basic.test
index db5768ac334..e93455337d6 100644
--- a/mysql-test/suite/sys_vars/t/gtid_seq_no_basic.test
+++ b/mysql-test/suite/sys_vars/t/gtid_seq_no_basic.test
@@ -9,5 +9,7 @@ SELECT @@session.gtid_seq_no;
 --error ER_LOCAL_VARIABLE
 SET GLOBAL gtid_seq_no= DEFAULT;
 
+SET SESSION gtid_seq_no= DEFAULT;
+
 SET SESSION gtid_seq_no= -1;
 SELECT @@session.gtid_seq_no;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 4768ad7dfb7..906ca75a6a9 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1800,6 +1800,13 @@ Sys_gtid_domain_id(
        ON_CHECK(check_gtid_domain_id));
 
 
+/*
+  Check that setting gtid_seq_no isn't done inside a transaction, and (in
+  gtid_strict_mode) doesn't create an out-of-order GTID sequence.
+
+  Setting gtid_seq_no to DEFAULT or 0 means we 'reset' it so that the value
+  doesn't affect the GTID of the next event group written to the binlog.
+*/
 static bool check_gtid_seq_no(sys_var *self, THD *thd, set_var *var)
 {
   uint32 domain_id, server_id;
@@ -1810,13 +1817,16 @@ static bool check_gtid_seq_no(sys_var *self, THD *thd, set_var *var)
                                                  ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO)))
     return true;
 
-  domain_id= thd->variables.gtid_domain_id;
-  server_id= thd->variables.server_id;
-  seq_no= (uint64)var->value->val_uint();
-  DBUG_EXECUTE_IF("ignore_set_gtid_seq_no_check", return 0;);
-  if (opt_gtid_strict_mode && opt_bin_log &&
-      mysql_bin_log.check_strict_gtid_sequence(domain_id, server_id, seq_no))
-    return true;
+  DBUG_EXECUTE_IF("ignore_set_gtid_seq_no_check", return false;);
+  if (var->value && opt_gtid_strict_mode && opt_bin_log)
+  {
+    domain_id= thd->variables.gtid_domain_id;
+    server_id= thd->variables.server_id;
+    seq_no= (uint64)var->value->val_uint();
+    if (seq_no != 0 &&
+        mysql_bin_log.check_strict_gtid_sequence(domain_id, server_id, seq_no))
+      return true;
+  }
 
   return false;
 }
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index ecb825940db..280e1c41afd 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -21616,6 +21616,7 @@ static void test_mdev_30159()
 
   result= mysql_list_fields(mysql, "v1", NULL);
   mytest(result);
+  mysql_free_result(result);
 
   rc= mysql_query(mysql, "drop view v1");
   myquery(rc);