diff --git a/changes/bug12191 b/changes/bug12191
new file mode 100644
index 0000000000000000000000000000000000000000..77589ab31133d2bb149559a7a538e3cbc06c5059
--- /dev/null
+++ b/changes/bug12191
@@ -0,0 +1,7 @@
+  o Minor bugfixes:
+
+    - We now drop CREATE cells for already-existent circuit IDs and
+      for zero-valued circuit IDs, regardless of other factors that
+      might otherwise have called for DESTROY cells.  Fixes bug 12191;
+      bugfix on 0.0.8pre1.
+
diff --git a/src/or/command.c b/src/or/command.c
index 105bdc637e0dafeca758f80e8472f6da004ff213..fa2a0e74e7cb2669b49f86fb7b2e7b4356f09271 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -227,6 +227,34 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
             (unsigned)cell->circ_id,
             U64_PRINTF_ARG(chan->global_identifier), chan);
 
+  /* We check for the conditions that would make us drop the cell before
+   * we check for the conditions that would make us send a DESTROY back,
+   * since those conditions would make a DESTROY nonsensical. */
+  if (cell->circ_id == 0) {
+    log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+           "Received a create cell (type %d) from %s with zero circID; "
+           " ignoring.", (int)cell->command,
+           channel_get_actual_remote_descr(chan));
+    return;
+  }
+
+  if (circuit_id_in_use_on_channel(cell->circ_id, chan)) {
+    const node_t *node = node_get_by_id(chan->identity_digest);
+    log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+           "Received CREATE cell (circID %u) for known circ. "
+           "Dropping (age %d).",
+           (unsigned)cell->circ_id,
+           (int)(time(NULL) - channel_when_created(chan)));
+    if (node) {
+      char *p = esc_for_log(node_get_platform(node));
+      log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+             "Details: router %s, platform %s.",
+             node_describe(node), p);
+      tor_free(p);
+    }
+    return;
+  }
+
   if (we_are_hibernating()) {
     log_info(LD_OR,
              "Received create cell but we're shutting down. Sending back "
@@ -248,14 +276,6 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
     return;
   }
 
-  if (cell->circ_id == 0) {
-    log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
-           "Received a create cell (type %d) from %s with zero circID; "
-           " ignoring.", (int)cell->command,
-           channel_get_actual_remote_descr(chan));
-    return;
-  }
-
   /* If the high bit of the circuit ID is not as expected, close the
    * circ. */
   if (chan->wide_circ_ids)
@@ -274,23 +294,6 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
     return;
   }
 
-  if (circuit_id_in_use_on_channel(cell->circ_id, chan)) {
-    const node_t *node = node_get_by_id(chan->identity_digest);
-    log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
-           "Received CREATE cell (circID %u) for known circ. "
-           "Dropping (age %d).",
-           (unsigned)cell->circ_id,
-           (int)(time(NULL) - channel_when_created(chan)));
-    if (node) {
-      char *p = esc_for_log(node_get_platform(node));
-      log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
-             "Details: router %s, platform %s.",
-             node_describe(node), p);
-      tor_free(p);
-    }
-    return;
-  }
-
   circ = or_circuit_new(cell->circ_id, chan);
   circ->base_.purpose = CIRCUIT_PURPOSE_OR;
   circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_ONIONSKIN_PENDING);