diff --git a/sexp.c b/sexp.c
index 194e23cff413f25b959aad196602011d93c490ae..bd60e29c95b16230717a598004390c1f1f515b0f 100644
--- a/sexp.c
+++ b/sexp.c
@@ -192,9 +192,19 @@ sexp_iterator_assoc(struct sexp_iterator *iterator,
 		    const struct sexp_assoc_key *keys,
 		    struct sexp_iterator *values)
 {
+  int *found;
+  unsigned nfound;
+  unsigned i;
+  
   if (!sexp_iterator_enter_list(iterator))
     return 0;
 
+  found = alloca(nkeys * sizeof(*found));
+  for (i = 0; i<nkeys; i++)
+    found[i] = 0;
+
+  nfound = 0;
+  
   for (;;)
     {
       if (!sexp_iterator_next(iterator))
@@ -212,13 +222,19 @@ sexp_iterator_assoc(struct sexp_iterator *iterator,
 	      && !iterator->display)
 	    {
 	      /* Compare to the given keys */
-	      unsigned i;
 	      for (i = 0; i<nkeys; i++)
 		{
 		  if (keys[i].length == iterator->atom_length
 		      && !memcmp(keys[i].name, iterator->atom,
 				 keys[i].length))
 		    {
+		      if (found[i])
+			/* We don't allow duplicates */
+			return 0;
+
+		      found[i] = 1;
+		      nfound++;
+		      
 		      /* Record this position. */
 		      values[i] = *iterator;
 
@@ -234,7 +250,8 @@ sexp_iterator_assoc(struct sexp_iterator *iterator,
 	  break;
 	  
 	case SEXP_END:
-	  return sexp_iterator_exit_list(iterator);
+	  return sexp_iterator_exit_list(iterator)
+	    && (nfound == nkeys);
 
 	default:
 	  abort();