diff --git a/CHANGES b/CHANGES
index 2a7338bf62921bda315655019767af05c5bbe85b..906009672fc1cbc6709d997322f022441ce2c1c8 100644
--- a/CHANGES
+++ b/CHANGES
@@ -13,6 +13,7 @@ OpenLDAP 2.4.20 Engineering
 	Added slapd syncrepl contextCSN storing in subentry (ITS#6373)
 	Fixed slapd asserts in minimal environment (ITS#6361)
 	Fixed slapd authid-rewrite parsing (ITS#6392) 
+	Fixed slapd checks of str2filter (ITS#6391)
 	Fixed slapd configArgs initialization (ITS#6363)
 	Fixed slapd debug handling of LDAP_DEBUG_ANY (ITS#6324)
 	Fixed slapd db_open with connection_fake_init (ITS#6381)
diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c
index b0f2763ce5975e4afeed0b22cf73256f0f22a195..b10320e4a627c30c94f4b4dd5497603aa552729f 100644
--- a/servers/slapd/overlays/pcache.c
+++ b/servers/slapd/overlays/pcache.c
@@ -768,6 +768,10 @@ url2query(
 		}
 		query.scope = lud->lud_scope;
 		query.filter = str2filter( lud->lud_filter );
+		if ( query.filter == NULL ) {
+			rc = -1;
+			goto error;
+		}
 
 		tempstr.bv_val = ch_malloc( strlen( lud->lud_filter ) + 1 );
 		tempstr.bv_len = 0;
@@ -2639,7 +2643,14 @@ pc_bind_attrs( Operation *op, Entry *e, QueryTemplate *temp,
 	}
 	*p2 = '\0';
 	op->o_tmpfree( vals, op->o_tmpmemctx );
-	return str2filter_x( op, fbv->bv_val );
+
+	/* FIXME: are we sure str2filter_x can't fail?
+	 * caller needs to check */
+	{
+		Filter *f = str2filter_x( op, fbv->bv_val );
+		assert( f != NULL );
+		return f;
+	}
 }
 
 /* Check if the requested entry is from the cache and has a valid
diff --git a/servers/slapd/overlays/retcode.c b/servers/slapd/overlays/retcode.c
index 31aa0b011ad566acb13b0a2e2cb6176966870031..15912540c8f2c2319212ba6b31b95442e8cbc8bb 100644
--- a/servers/slapd/overlays/retcode.c
+++ b/servers/slapd/overlays/retcode.c
@@ -257,6 +257,9 @@ retcode_op_internal( Operation *op, SlapReply *rs )
 		1, &op2.ors_filterstr, op2.o_tmpmemctx );
 	op2.ors_filter = str2filter_x( &op2, op2.ors_filterstr.bv_val );
 
+	/* errAbsObject is defined by this overlay! */
+	assert( op2.ors_filter != NULL );
+
 	db.bd_info = on->on_info->oi_orig;
 	op2.o_bd = &db;
 
diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c
index 703fe25a6bb5c096177387df6d4ce337406fbccb..723732f2e7cb668891c92833b890743a8ef39164 100644
--- a/servers/slapd/syncrepl.c
+++ b/servers/slapd/syncrepl.c
@@ -75,6 +75,7 @@ typedef struct syncinfo_s {
 	struct berval		si_base;
 	struct berval		si_logbase;
 	struct berval		si_filterstr;
+	Filter			*si_filter;
 	struct berval		si_logfilterstr;
 	struct berval		si_contextdn;
 	int			si_scope;
@@ -2724,7 +2725,7 @@ syncrepl_del_nonpresent(
 		op->ors_tlimit = SLAP_NO_LIMIT;
 		op->ors_limit = NULL;
 		op->ors_attrsonly = 0;
-		op->ors_filter = str2filter_x( op, si->si_filterstr.bv_val );
+		op->ors_filter = filter_dup( si->si_filter, op->o_tmpmemctx );
 		/* In multimaster, updates can continue to arrive while
 		 * we're searching. Limit the search result to entries
 		 * older than our newest cookie CSN.
@@ -3760,6 +3761,9 @@ syncinfo_free( syncinfo_t *sie, int free_all )
 		if ( sie->si_filterstr.bv_val ) {
 			ch_free( sie->si_filterstr.bv_val );
 		}
+		if ( sie->si_filter ) {
+			filter_free( sie->si_filter );
+		}
 		if ( sie->si_logfilterstr.bv_val ) {
 			ch_free( sie->si_logfilterstr.bv_val );
 		}
@@ -4372,6 +4376,13 @@ parse_syncrepl_line(
 		}
 	}
 
+	si->si_filter = str2filter( si->si_filterstr.bv_val );
+	if ( si->si_filter == NULL ) {
+		Debug( LDAP_DEBUG_ANY, "syncrepl %s " SEARCHBASESTR "=\"%s\": unable to parse filter=\"%s\"\n", 
+			si->si_ridtxt, c->be->be_suffix ? c->be->be_suffix[ 0 ].bv_val : "(null)", si->si_filterstr.bv_val );
+		return 1;
+	}
+
 	return 0;
 }