diff --git a/main/ccss.c b/main/ccss.c
index ad1d76ed54260738e5626ff8b949264b8a28bf7a..583c7389c72c3a4bc567158102dafc336a3b79cd 100644
--- a/main/ccss.c
+++ b/main/ccss.c
@@ -990,6 +990,22 @@ struct generic_monitor_instance {
 struct generic_monitor_instance_list {
 	const char *device_name;
 	enum ast_device_state current_state;
+	/* If there are multiple instances monitoring the
+	 * same device and one should fail, we need to know
+	 * whether to signal that the device can be recalled.
+	 * The problem is that the device state is not enough
+	 * to check. If a caller has requested CCNR, then the
+	 * fact that the device is available does not indicate
+	 * that the device is ready to be recalled. Instead, as
+	 * soon as one instance of the monitor becomes available
+	 * for a recall, we mark the entire list as being fit
+	 * for recall. If a CCNR request comes in, then we will
+	 * have to mark the list as unfit for recall since this
+	 * is a clear indicator that the person at the monitored
+	 * device has gone away and is actuall not fit to be
+	 * recalled
+	 */
+	int fit_for_recall;
 	struct ast_event_sub *sub;
 	AST_LIST_HEAD_NOLOCK(, generic_monitor_instance) list;
 };
@@ -1112,6 +1128,7 @@ static int generic_monitor_devstate_tp_cb(void *data)
 		AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
 			if (!generic_instance->is_suspended && generic_instance->monitoring) {
 				generic_instance->monitoring = 0;
+				generic_list->fit_for_recall = 1;
 				ast_cc_monitor_callee_available(generic_instance->core_id, "Generic monitored party has become available");
 				break;
 			}
@@ -1209,6 +1226,12 @@ static int cc_generic_monitor_request_cc(struct ast_cc_monitor *monitor, int *av
 		cc_unref(generic_list, "Failed to schedule available timer. (generic_list)");
 		return -1;
 	}
+	/* If the new instance was created as CCNR, then that means this device is not currently
+	 * fit for recall even if it previously was.
+	 */
+	if (service == AST_CC_CCNR || service == AST_CC_CCNL) {
+		generic_list->fit_for_recall = 0;
+	}
 	ast_cc_monitor_request_acked(monitor->core_id, "Generic monitor for %s subscribed to device state.",
 			monitor->interface->device_name);
 	cc_unref(generic_list, "Finished with monitor instance reference in request cc callback");
@@ -1343,6 +1366,27 @@ static void cc_generic_monitor_destructor(void *private_data)
 		 * list from the container
 		 */
 		ao2_t_unlink(generic_monitors, generic_list, "Generic list is empty. Unlink it from the container");
+	} else {
+		/* There are still instances for this particular device. The situation
+		 * may be that we were attempting a CC recall and a failure occurred, perhaps
+		 * on the agent side. If a failure happens here and the device being monitored
+		 * is available, then we need to signal on the first unsuspended instance that
+		 * the device is available for recall.
+		 */
+
+		/* First things first. We don't even want to consider this action if
+		 * the device in question isn't available right now.
+		 */
+		if (generic_list->fit_for_recall && (generic_list->current_state == AST_DEVICE_NOT_INUSE ||
+				generic_list->current_state == AST_DEVICE_UNKNOWN)) {
+			AST_LIST_TRAVERSE(&generic_list->list, generic_instance, next) {
+				if (!generic_instance->is_suspended && generic_instance->monitoring) {
+					ast_cc_monitor_callee_available(generic_instance->core_id, "Signaling generic monitor "
+							"availability due to other instance's failure.");
+					break;
+				}
+			}
+		}
 	}
 	cc_unref(generic_list, "Done with generic list in generic monitor destructor");
 	ast_free((char *)gen_mon_pvt->device_name);
@@ -2848,8 +2892,6 @@ static int cc_complete(struct cc_core_instance *core_instance, struct cc_state_c
 
 static int cc_failed(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
 {
-	/* Something along the way failed, call agent and monitor destructor functions
-	 */
 	manager_event(EVENT_FLAG_CC, "CCFailure",
 		"CoreID: %d\r\n"
 		"Caller: %s\r\n"