diff --git a/src/common/assoc_mgr.c b/src/common/assoc_mgr.c
index 26d8c647579a7ed0e32e711c4cad1052fa348cbe..d8f9d7fca4afa2efc19f998a4d4cea96f9bdd387 100644
--- a/src/common/assoc_mgr.c
+++ b/src/common/assoc_mgr.c
@@ -1039,6 +1039,12 @@ extern int assoc_mgr_fill_in_assoc(void *db_conn, acct_association_rec_t *assoc,
 	assoc->max_submit_jobs = ret_assoc->max_submit_jobs;
 	assoc->max_wall_pj     = ret_assoc->max_wall_pj;
 
+	if(assoc->valid_qos) {
+		FREE_NULL_BITMAP(assoc->valid_qos);
+		assoc->valid_qos = bit_copy(ret_assoc->valid_qos);
+	} else
+		assoc->valid_qos = ret_assoc->valid_qos;
+
 	if(assoc->parent_acct) {
 		xfree(assoc->parent_acct);
 		assoc->parent_acct       = xstrdup(ret_assoc->parent_acct);
@@ -1116,6 +1122,7 @@ extern int assoc_mgr_fill_in_user(void *db_conn, acct_user_rec_t *user,
 
 extern int assoc_mgr_fill_in_qos(void *db_conn, acct_qos_rec_t *qos,
 				 int enforce,
+				 acct_association_rec_t *assoc_ptr,
 				 acct_qos_rec_t **qos_pptr)
 {
 	ListIterator itr = NULL;
@@ -1147,6 +1154,17 @@ extern int assoc_mgr_fill_in_qos(void *db_conn, acct_qos_rec_t *qos,
 			return SLURM_ERROR;
 		else
 			return SLURM_SUCCESS;
+	} else if(assoc_ptr) {
+		if(enforce 
+		   && (!assoc_ptr->valid_qos 
+		       || !bit_test(assoc_ptr->valid_qos, found_qos->id))) {
+			error("This association %d(account='%s', "
+			      "user='%s', partition='%s' does not have "
+			      "access to qos %s", 
+			      assoc_ptr->id, assoc_ptr->acct, assoc_ptr->user,
+			      assoc_ptr->partition, found_qos->name);
+			return SLURM_ERROR;
+		}			
 	}
 
 	debug3("found correct qos");
diff --git a/src/common/assoc_mgr.h b/src/common/assoc_mgr.h
index a2c3e9dc15e1439dc2bd32378d1a6ad6fef2899f..b2658d20c206c50a32cf58cdb715e67c1df2e0b6 100644
--- a/src/common/assoc_mgr.h
+++ b/src/common/assoc_mgr.h
@@ -127,6 +127,10 @@ extern int assoc_mgr_fill_in_user(void *db_conn, acct_user_rec_t *user,
 /* 
  * get info from the storage 
  * IN/OUT:  qos - acct_qos_rec_t with the id set of the qos.
+ * IN:      assoc_ptr - acct_association_rec_t with the valid_qos
+ *                      bitstring avaliable to check against.  If this
+ *                      is NULL no checking is done, if not NULL we
+ *                      validate if this qos is usable by this association.
  * IN/OUT:  qos_pptr - if non-NULL then return a pointer to the 
  *		       acct_qos record in cache on success
  *                     DO NOT FREE.
@@ -134,6 +138,7 @@ extern int assoc_mgr_fill_in_user(void *db_conn, acct_user_rec_t *user,
  */
 extern int assoc_mgr_fill_in_qos(void *db_conn, acct_qos_rec_t *qos,
 				 int enforce,
+				 acct_association_rec_t *assoc_ptr,
 				 acct_qos_rec_t **qos_pptr);
 /* 
  * get info from the storage 
diff --git a/src/slurmctld/controller.c b/src/slurmctld/controller.c
index 9da82058f28ec7ad7464c3959e8fa01a0b18c383..0c8404c72abd75d5b50de0169932c515667ebfb3 100644
--- a/src/slurmctld/controller.c
+++ b/src/slurmctld/controller.c
@@ -1746,20 +1746,6 @@ static void *_assoc_cache_mgr(void *no_data)
 	       list_count(job_list));
 	itr = list_iterator_create(job_list);
 	while ((job_ptr = list_next(itr))) {
-		if(job_ptr->qos) {
-			memset(&qos_rec, 0, sizeof(acct_qos_rec_t));
-			qos_rec.id = job_ptr->qos;
-			if((assoc_mgr_fill_in_qos(
-				    acct_db_conn, &qos_rec,
-				    accounting_enforce,
-				    (acct_qos_rec_t **)&job_ptr->qos_ptr))
-			   != SLURM_SUCCESS) {
-				verbose("Invalid qos (%u) for job_id %u",
-					job_ptr->qos, job_ptr->job_id);
-				/* not a fatal error, qos could have
-				 * been removed */
-			} 
-		}
 		if(job_ptr->assoc_id) {
 			memset(&assoc_rec, 0, sizeof(acct_association_rec_t));
 			assoc_rec.id = job_ptr->assoc_id;
@@ -1784,6 +1770,21 @@ static void *_assoc_cache_mgr(void *no_data)
 			      job_ptr->assoc_ptr, job_ptr->assoc_id, 
 			      job_ptr->job_id);
 		}
+		if(job_ptr->qos) {
+			memset(&qos_rec, 0, sizeof(acct_qos_rec_t));
+			qos_rec.id = job_ptr->qos;
+			if((assoc_mgr_fill_in_qos(
+				    acct_db_conn, &qos_rec,
+				    accounting_enforce,
+				    NULL,
+				    (acct_qos_rec_t **)&job_ptr->qos_ptr))
+			   != SLURM_SUCCESS) {
+				verbose("Invalid qos (%u) for job_id %u",
+					job_ptr->qos, job_ptr->job_id);
+				/* not a fatal error, qos could have
+				 * been removed */
+			} 
+		}
 	}
 	list_iterator_destroy(itr);
 	unlock_slurmctld(job_write_lock);
diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c
index 89e748bd2580507b1e1b1e9d060621c18a46f934..6771046245e98b045c91e966d3d785e65249aa2d 100644
--- a/src/slurmctld/job_mgr.c
+++ b/src/slurmctld/job_mgr.c
@@ -850,19 +850,6 @@ static int _load_job_state(Buf buffer)
 		_add_job_hash(job_ptr);
 	}
 
-	if(qos) {
-		memset(&qos_rec, 0, sizeof(acct_qos_rec_t));
-		qos_rec.id = qos;
-		if((assoc_mgr_fill_in_qos(acct_db_conn, &qos_rec,
-					  accounting_enforce, 
-					  (acct_qos_rec_t **)
-					  &job_ptr->qos_ptr))
-		   != SLURM_SUCCESS) {
-			verbose("Invalid qos (%u) for job_id %u", qos, job_id);
-			/* not a fatal error, qos could have been removed */
-		} 
-	}
-
 	if ((maximum_prio >= priority) && (priority > 1))
 		maximum_prio = priority;
 	if (job_id_sequence <= job_id)
@@ -1009,6 +996,28 @@ static int _load_job_state(Buf buffer)
 			jobacct_storage_g_job_complete(acct_db_conn, job_ptr);
 	}
 
+	if(job_ptr->qos) {
+		memset(&qos_rec, 0, sizeof(acct_qos_rec_t));
+		qos_rec.id = job_ptr->qos;
+		if((assoc_mgr_fill_in_qos(acct_db_conn, &qos_rec,
+					  accounting_enforce, 
+					  (acct_association_rec_t *)
+					  job_ptr->assoc_ptr,
+					  (acct_qos_rec_t **)
+					  &job_ptr->qos_ptr))
+		   != SLURM_SUCCESS) {
+			info("Cancelling job %u with invalid qos",
+			     job_id);
+			job_ptr->job_state = JOB_CANCELLED;
+			job_ptr->state_reason = FAIL_BANK_ACCOUNT;
+			xfree(job_ptr->state_desc);
+			if (IS_JOB_PENDING(job_ptr))
+				job_ptr->start_time = now;
+			job_ptr->end_time = now;
+			job_completion_logger(job_ptr);
+		} 
+	}
+
 	safe_unpack16(&step_flag, buffer);
 	while (step_flag == STEP_FLAG) {
 		/* No need to put these into accounting if they
@@ -3349,8 +3358,9 @@ _copy_job_desc_to_job_record(job_desc_msg_t * job_desc,
 		else
 			qos_rec.name = "normal";
 	}
-	if((assoc_mgr_fill_in_qos(acct_db_conn, &qos_rec, accounting_enforce,
-				  (acct_qos_rec_t **) &job_ptr->qos_ptr))
+	if(assoc_mgr_fill_in_qos(acct_db_conn, &qos_rec, accounting_enforce,
+				 (acct_association_rec_t *) job_ptr->assoc_ptr,
+				 (acct_qos_rec_t **) &job_ptr->qos_ptr)
 	   != SLURM_SUCCESS) {
 		error("Invalid qos (%s) for job_id %u", qos_rec.name,
 		      job_ptr->job_id);
@@ -4822,6 +4832,8 @@ int update_job(job_desc_msg_t * job_specs, uid_t uid)
 			
 			if((assoc_mgr_fill_in_qos(acct_db_conn, &qos_rec,
 						  accounting_enforce,
+						  (acct_association_rec_t *) 
+						  job_ptr->assoc_ptr,
 						  (acct_qos_rec_t **)
 						  &job_ptr->qos_ptr))
 			   != SLURM_SUCCESS) {