diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index a86245b9f4c4dbddb9221570047d3de7d606b3f6..85f0fc7772129d7a1f97bef3691a0851cd5d21ce 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -31,9 +31,12 @@
 #include "routerparse.h"
 #include "routerset.h"
 
+struct rend_service_t;
 static origin_circuit_t *find_intro_circuit(rend_intro_point_t *intro,
                                             const char *pk_digest);
 static rend_intro_point_t *find_intro_point(origin_circuit_t *circ);
+static rend_intro_point_t *find_expiring_intro_point(
+    struct rend_service_t *service, origin_circuit_t *circ);
 
 static extend_info_t *find_rp_for_intro(
     const rend_intro_cell_t *intro,
@@ -42,7 +45,6 @@ static extend_info_t *find_rp_for_intro(
 static int intro_point_accepted_intro_count(rend_intro_point_t *intro);
 static int intro_point_should_expire_now(rend_intro_point_t *intro,
                                          time_t now);
-struct rend_service_t;
 static int rend_service_derive_key_digests(struct rend_service_t *s);
 static int rend_service_load_keys(struct rend_service_t *s);
 static int rend_service_load_auth_keys(struct rend_service_t *s,
@@ -1503,12 +1505,15 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
 
   intro_point = find_intro_point(circuit);
   if (intro_point == NULL) {
-    log_warn(LD_BUG,
-             "Internal error: Got an INTRODUCE2 cell on an "
-             "intro circ (for service %s) with no corresponding "
-             "rend_intro_point_t.",
-             escaped(serviceid));
-    goto err;
+    intro_point = find_expiring_intro_point(service, circuit);
+    if (intro_point == NULL) {
+      log_warn(LD_BUG,
+               "Internal error: Got an INTRODUCE2 cell on an "
+               "intro circ (for service %s) with no corresponding "
+               "rend_intro_point_t.",
+               escaped(serviceid));
+      goto err;
+    }
   }
 
   log_info(LD_REND, "Received INTRODUCE2 cell for service %s on circ %u.",
@@ -2688,8 +2693,8 @@ rend_service_launch_establish_intro(rend_service_t *service,
   return 0;
 }
 
-/** Return the number of introduction points that are or have been
- * established for the given service. */
+/** Return the number of introduction points that are established for the
+ * given service. */
 static unsigned int
 count_established_intro_points(const rend_service_t *service)
 {
@@ -2701,6 +2706,30 @@ count_established_intro_points(const rend_service_t *service)
   return num;
 }
 
+/** Return the number of introduction points that are or are being
+ * established for the given service. This function iterates over all
+ * circuit and count those that are linked to the service and are waiting
+ * for the intro point to respond. */
+static unsigned int
+count_intro_point_circuits(const rend_service_t *service)
+{
+  unsigned int num_ipos = 0;
+  SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
+    if (!circ->marked_for_close &&
+        circ->state == CIRCUIT_STATE_OPEN &&
+        (circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
+         circ->purpose == CIRCUIT_PURPOSE_S_INTRO)) {
+      origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(circ);
+      if (oc->rend_data &&
+          !rend_cmp_service_ids(service->service_id,
+                                oc->rend_data->onion_address))
+        num_ipos++;
+    }
+  }
+  SMARTLIST_FOREACH_END(circ);
+  return num_ipos;
+}
+
 /** Called when we're done building a circuit to an introduction point:
  *  sends a RELAY_ESTABLISH_INTRO cell.
  */
@@ -2739,7 +2768,8 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
    * redefine this one as a general circuit or close it, depending.
    * Substract the amount of expiring nodes here since the circuits are
    * still opened. */
-  if (count_established_intro_points(service) >
+  if ((count_intro_point_circuits(service) -
+       smartlist_len(service->expiring_nodes)) >
       service->n_intro_points_wanted) {
     const or_options_t *options = get_options();
     /* Remove the intro point associated with this circuit, it's being
@@ -3053,6 +3083,23 @@ find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest)
   return NULL;
 }
 
+/** Return the corresponding introdution point using the circuit <b>circ</b>
+ * found in the <b>service</b>. NULL is returned if not found. */
+static rend_intro_point_t *
+find_expiring_intro_point(rend_service_t *service, origin_circuit_t *circ)
+{
+  tor_assert(service);
+  tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
+             TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_S_INTRO);
+
+  SMARTLIST_FOREACH(service->intro_nodes, rend_intro_point_t *, intro_point,
+    if (crypto_pk_eq_keys(intro_point->intro_key, circ->intro_key)) {
+      return intro_point;
+  });
+
+  return NULL;
+}
+
 /** Return a pointer to the rend_intro_point_t corresponding to the
  * service-side introduction circuit <b>circ</b>. */
 static rend_intro_point_t *
@@ -3654,10 +3701,10 @@ rend_consider_services_upload(time_t now)
     /* Does every introduction points have been established? */
     unsigned int intro_points_ready =
       count_established_intro_points(service) >= service->n_intro_points_wanted;
-    if (service->next_upload_time < now ||
+    if (intro_points_ready &&
+        (service->next_upload_time < now ||
         (service->desc_is_dirty &&
-         service->desc_is_dirty < now-rendinitialpostdelay &&
-         intro_points_ready)) {
+         service->desc_is_dirty < now-rendinitialpostdelay))) {
       /* if it's time, or if the directory servers have a wrong service
        * descriptor and ours has been stable for rendinitialpostdelay seconds,
        * upload a new one of each format. */