char    cLastWritten[MAX_TIME_LENGTH];  /* LastWritten returned from DB */
    char    cLabelDate[MAX_TIME_LENGTH];    /* LabelData returned from DB */
    char    cInitialWrite[MAX_TIME_LENGTH]; /* InitialWrite returned from DB */
+   char   *exclude_list;                   /* Optionnal exclude list for db_find_next_volume() */
    bool    set_first_written;
    bool    set_label_date;
 };
 
    } else {
       POOL_MEM changer(PM_FNAME);
       POOL_MEM voltype(PM_FNAME);
+      POOL_MEM exclude(PM_FNAME);
       /* Find next available volume */
       if (InChanger) {
          Mmsg(changer, " AND InChanger=1 AND StorageId=%s ",
                  edit_int64(mr->StorageId, ed1));
       }
+      /* Volumes will be automatically excluded from the query, we just take the
+       * first one of the list 
+       */
+      if (mr->exclude_list && *mr->exclude_list) {
+         item = 1;
+         Mmsg(exclude, " AND MediaId NOT IN (%s) ", mr->exclude_list);
+      }
       if (strcmp(mr->VolStatus, "Recycle") == 0 ||
           strcmp(mr->VolStatus, "Purged") == 0) {
          order = "AND Recycle=1 ORDER BY LastWritten ASC,MediaId";  /* take oldest that can be recycled */
          "AND VolStatus='%s' "
          "%s "
          "%s "
+         "%s "
          "%s LIMIT %d",
          edit_int64(mr->PoolId, ed1), esc_type,
          esc_status,
          voltype.c_str(),
-         changer.c_str(), order, item);
+         changer.c_str(), exclude.c_str(), order, item);
    }
    Dmsg1(100, "fnextvol=%s\n", cmd);
    if (!QueryDB(jcr, cmd)) {
 
    free_and_null_pool_memory(jcr->rpool_source);
    free_and_null_pool_memory(jcr->wstore_source);
    free_and_null_pool_memory(jcr->rstore_source);
+   free_and_null_pool_memory(jcr->next_vol_list);
 
    /* Delete lists setup to hold storage pointers */
    free_rwstorage(jcr);
       jcr->setJobLevel(job->JobLevel);
       break;
    }
-
+   if (!jcr->next_vol_list) {
+      jcr->next_vol_list = get_pool_memory(PM_FNAME);
+   }
    if (!jcr->fname) {
       jcr->fname = get_pool_memory(PM_FNAME);
    }
 
    mr->StorageId = store->StorageId;
 }
 
+static void add_volume_to_exclude_list(JCR *jcr, int index, MEDIA_DBR *mr)
+{
+   char ed1[50];
+   if (index == 1) {
+      *jcr->next_vol_list = 0;
+
+   } else if (*jcr->next_vol_list) {
+      pm_strcat(jcr->next_vol_list, ",");
+   }
+   pm_strcat(jcr->next_vol_list, edit_int64(mr->MediaId, ed1));
+
+   /* The list is valid only in find_next_volume_for_append() */
+   mr->exclude_list = NULL;
+}
+
+static void set_volume_to_exclude_list(JCR *jcr, int index, MEDIA_DBR *mr)
+{
+   if (index == 1) {
+      *jcr->next_vol_list = 0;
+   }
+   mr->exclude_list = jcr->next_vol_list;
+}
+
 /*
  *  Items needed:
  *   mr.PoolId must be set
     */
    InChanger = (store->autochanger)? true : false;
 
+   /* Make sure we don't send two times the same volume in the same session */
+   set_volume_to_exclude_list(jcr, index, mr);
+
    /*
     * Find the Next Volume for Append
     */
    } /* end for loop */
    db_unlock(jcr->db);
    Dmsg1(dbglvl, "return ok=%d find_next_vol\n", ok);
+
+   /* We keep the record of all previous volumes requested */
+   if (ok) {
+      add_volume_to_exclude_list(jcr, index, mr);;
+   }
    return ok;
 }
 
 
    POOLMEM *rstore_source;            /* Where read storage came from */
    POOLMEM *wstore_source;            /* Where write storage came from */
    POOLMEM *catalog_source;           /* Where catalog came from */
+   POOLMEM *next_vol_list;            /* Volumes previously requested */
    uint32_t replace;                  /* Replace option */
    int32_t NumVols;                   /* Number of Volume used in pool */
    int32_t reschedule_count;          /* Number of times rescheduled */