diff --git a/CHANGES b/CHANGES
index cbf39b1df548d502b053ad74261d50214fadf294..500c354d1af4593616b31ffda994e49455f3e5cc 100644
--- a/CHANGES
+++ b/CHANGES
@@ -12,6 +12,7 @@ OpenLDAP 2.4.16 Engineering
 	Fixed slapd syncrepl newCookie sync messages (ITS#5972)
 	Fixed slapd syncrepl hang during shutdown (ITS#6011)
 	Fixed slapd syncrepl too many MMR messages (ITS#6020)
+	Fixed slapd syncrepl skipped entries with MMR (ITS#5988)
 	Fixed slapd-bdb/hdb cachesize handling (ITS#5860)
 	Fixed slapd-bdb/hdb with slapcat with empty dn (ITS#6006)
 	Fixed slapd-ldap incorrect referral handling (ITS#6003,ITS#5916)
@@ -23,6 +24,7 @@ OpenLDAP 2.4.16 Engineering
 	Fixed slapd-syncprov too many MMR messages (ITS#6020)
 	Fixed slapo-syncprov replica lockout (ITS#5985)
 	Fixed slapo-syncprov modtarget tracking (ITS#5999)
+	Fixed slapo-syncprov skipped entries with MMR (ITS#5988)
 	Build Environment
 		Cleaned up alloc/free functions for Windows (ITS#6005)
 	Documentation
diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c
index 6799e03c79dfedb72173c1286feba1fe5a3fe1e7..f3c6e483db39afee80d7da30b297fe101cde9265 100644
--- a/servers/slapd/overlays/syncprov.c
+++ b/servers/slapd/overlays/syncprov.c
@@ -2377,13 +2377,32 @@ syncprov_op_search( Operation *op, SlapReply *rs )
 
 		/* If nothing has changed, shortcut it */
 		if ( srs->sr_state.numcsns == numcsns ) {
-			int i, j;
+			int i, j, newer;
 			for ( i=0; i<srs->sr_state.numcsns; i++ ) {
 				for ( j=0; j<numcsns; j++ ) {
 					if ( srs->sr_state.sids[i] != sids[j] )
 						continue;
-					if ( !bvmatch( &srs->sr_state.ctxcsn[i], &ctxcsn[j] ))
+					newer = ber_bvcmp( &srs->sr_state.ctxcsn[i], &ctxcsn[j] );
+					/* If our state is newer, tell consumer about changes */
+					if ( newer < 0 )
 						changed = SS_CHANGED;
+					else if ( newer > 0 ) {
+					/* our state is older, tell consumer nothing */
+						if ( sop ) {
+							syncops **sp = &si->si_ops;
+							
+							ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
+							while ( *sp != sop )
+								sp = &(*sp)->s_next;
+							*sp = sop->s_next;
+							ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
+							ch_free( sop );
+						}
+						rs->sr_err = LDAP_SUCCESS;
+						rs->sr_ctrls = NULL;
+						send_ldap_result( op, rs );
+						return rs->sr_err;
+					}
 					break;
 				}
 				if ( changed )
diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c
index 76b9ec1a97c4e11bbff14032787d0d678f1b9dac..e6a9a43f7f49d556a39a7f80e76c881ac881d366 100644
--- a/servers/slapd/syncrepl.c
+++ b/servers/slapd/syncrepl.c
@@ -1588,6 +1588,7 @@ syncrepl_message_to_op(
 		prdn = BER_BVNULL, nrdn = BER_BVNULL,
 		psup = BER_BVNULL, nsup = BER_BVNULL;
 	int		rc, deleteOldRdn = 0, freeReqDn = 0;
+	int		do_graduate = 0;
 
 	if ( ldap_msgtype( msg ) != LDAP_RES_SEARCH_ENTRY ) {
 		Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_op: %s "
@@ -1656,6 +1657,7 @@ syncrepl_message_to_op(
 			&slap_schema.si_ad_entryCSN->ad_cname ) )
 		{
 			slap_queue_csn( op, bvals );
+			do_graduate = 1;
 		}
 		ch_free( bvals );
 	}
@@ -1700,6 +1702,7 @@ syncrepl_message_to_op(
 				Debug( LDAP_DEBUG_SYNC,
 					"syncrepl_message_to_op: %s be_add %s (%d)\n", 
 					si->si_ridtxt, op->o_req_dn.bv_val, rc );
+				do_graduate = 0;
 			}
 			if ( e == op->ora_e )
 				be_entry_release_w( op, op->ora_e );
@@ -1712,6 +1715,7 @@ syncrepl_message_to_op(
 				"syncrepl_message_to_op: %s be_modify %s (%d)\n", 
 				si->si_ridtxt, op->o_req_dn.bv_val, rc );
 			op->o_bd = si->si_be;
+			do_graduate = 0;
 		}
 		break;
 	case LDAP_REQ_MODRDN:
@@ -1755,16 +1759,19 @@ syncrepl_message_to_op(
 		Debug( rc ? LDAP_DEBUG_ANY : LDAP_DEBUG_SYNC,
 			"syncrepl_message_to_op: %s be_modrdn %s (%d)\n", 
 			si->si_ridtxt, op->o_req_dn.bv_val, rc );
+		do_graduate = 0;
 		break;
 	case LDAP_REQ_DELETE:
 		rc = op->o_bd->be_delete( op, &rs );
 		Debug( rc ? LDAP_DEBUG_ANY : LDAP_DEBUG_SYNC,
 			"syncrepl_message_to_op: %s be_delete %s (%d)\n", 
 			si->si_ridtxt, op->o_req_dn.bv_val, rc );
+		do_graduate = 0;
 		break;
 	}
 done:
-	slap_graduate_commit_csn( op );
+	if ( do_graduate )
+		slap_graduate_commit_csn( op );
 	op->o_bd = si->si_be;
 	op->o_tmpfree( op->o_csn.bv_val, op->o_tmpmemctx );
 	BER_BVZERO( &op->o_csn );
@@ -2241,6 +2248,7 @@ retry_add:;
 					si->si_ridtxt, rs_add.sr_err, 0 );
 				break;
 			}
+			syncCSN = NULL;
 			op->o_bd = be;
 			goto done;
 		}
@@ -2440,7 +2448,9 @@ retry_add:;
 			op->o_req_dn = entry->e_name;
 			op->o_req_ndn = entry->e_nname;
 			/* Use CSN on the modify */
-			if ( syncCSN && !just_rename )
+			if ( just_rename )
+				syncCSN = NULL;
+			else if ( syncCSN )
 				slap_queue_csn( op, syncCSN );
 		}
 		if ( dni.mods ) {
@@ -2460,11 +2470,16 @@ retry_add:;
 					"syncrepl_entry: %s be_modify failed (%d)\n",
 					si->si_ridtxt, rs_modify.sr_err, 0 );
 			}
+			syncCSN = NULL;
 			op->o_bd = be;
 		} else if ( !dni.renamed ) {
 			Debug( LDAP_DEBUG_SYNC,
 					"syncrepl_entry: %s entry unchanged, ignored (%s)\n", 
 					si->si_ridtxt, op->o_req_dn.bv_val, 0 );
+			if ( syncCSN ) {
+				slap_graduate_commit_csn( op );
+				syncCSN = NULL;
+			}
 		}
 		goto done;
 	case LDAP_SYNC_DELETE :
@@ -2493,6 +2508,7 @@ retry_add:;
 					break;
 				}
 			}
+			syncCSN = NULL;
 			op->o_bd = be;
 		}
 		goto done;