diff --git a/include/asterisk/stasis_app.h b/include/asterisk/stasis_app.h
index a73461547e0f977356744361dee518f435606419..3497bf437af5348daa2bd85664036ab4a45eeb01 100644
--- a/include/asterisk/stasis_app.h
+++ b/include/asterisk/stasis_app.h
@@ -740,6 +740,15 @@ int stasis_app_bridge_playback_channel_add(struct ast_bridge *bridge,
 	struct ast_channel *chan,
 	struct stasis_app_control *control);
 
+/*!
+ * \brief remove channel from list of ARI playback channels for bridges.
+ *
+ * \param bridge_id The unique ID of the bridge the playback channel is in.
+ * \param control The app control structure for the playback channel
+ */
+void stasis_app_bridge_playback_channel_remove(char *bridge_id,
+	struct stasis_app_control *control);
+
 /*!
  * \brief Result codes used when adding/removing channels to/from bridges.
  */
diff --git a/res/ari/resource_bridges.c b/res/ari/resource_bridges.c
index cec443dbab4db23d79f13938a5905725c1f1bf57..28c3e43605217b3df433feacae05633ef6ac2746 100644
--- a/res/ari/resource_bridges.c
+++ b/res/ari/resource_bridges.c
@@ -278,6 +278,7 @@ struct bridge_channel_control_thread_data {
 	struct ast_channel *bridge_channel;
 	struct stasis_app_control *control;
 	struct stasis_forward *forward;
+	char bridge_id[0];
 };
 
 static void *bridge_channel_control_thread(void *data)
@@ -287,6 +288,7 @@ static void *bridge_channel_control_thread(void *data)
 	struct stasis_app_control *control = thread_data->control;
 	struct stasis_forward *forward = thread_data->forward;
 	ast_callid callid = ast_channel_callid(bridge_channel);
+	char *bridge_id = ast_strdupa(thread_data->bridge_id);
 
 	if (callid) {
 		ast_callid_threadassoc_add(callid);
@@ -298,6 +300,7 @@ static void *bridge_channel_control_thread(void *data)
 	stasis_app_control_execute_until_exhausted(bridge_channel, control);
 	stasis_app_control_flush_queue(control);
 
+	stasis_app_bridge_playback_channel_remove(bridge_id, control);
 	stasis_forward_cancel(forward);
 	ao2_cleanup(control);
 	ast_hangup(bridge_channel);
@@ -466,8 +469,9 @@ static void ari_bridges_play_new(const char **args_media,
 	}
 
 	/* Give play_channel and control reference to the thread data */
-	thread_data = ast_calloc(1, sizeof(*thread_data));
+	thread_data = ast_malloc(sizeof(*thread_data) + strlen(bridge->uniqueid) + 1);
 	if (!thread_data) {
+		stasis_app_bridge_playback_channel_remove((char *)bridge->uniqueid, control);
 		ast_ari_response_alloc_failed(response);
 		return;
 	}
@@ -475,8 +479,11 @@ static void ari_bridges_play_new(const char **args_media,
 	thread_data->bridge_channel = play_channel;
 	thread_data->control = control;
 	thread_data->forward = channel_forward;
+	/* Safe */
+	strcpy(thread_data->bridge_id, bridge->uniqueid);
 
 	if (ast_pthread_create_detached(&threadid, NULL, bridge_channel_control_thread, thread_data)) {
+		stasis_app_bridge_playback_channel_remove((char *)bridge->uniqueid, control);
 		ast_ari_response_alloc_failed(response);
 		ast_free(thread_data);
 		return;
diff --git a/res/res_stasis.c b/res/res_stasis.c
index e7e6bcaa3179903992c58b8b2a11253b9782f197..464f7c42f1b228ea18bf7e8998164f12a1457e6a 100644
--- a/res/res_stasis.c
+++ b/res/res_stasis.c
@@ -713,6 +713,22 @@ int stasis_app_bridge_playback_channel_add(struct ast_bridge *bridge,
 	return 0;
 }
 
+void stasis_app_bridge_playback_channel_remove(char *bridge_id,
+	struct stasis_app_control *control)
+{
+	struct stasis_app_bridge_channel_wrapper *wrapper;
+
+	wrapper = ao2_find(app_bridges_playback, bridge_id, OBJ_SEARCH_KEY | OBJ_UNLINK);
+	if (wrapper) {
+		/* If wrapper is not found, then that means the after bridge callback has been
+		 * called or is in progress. No need to unlink the control here since that has
+		 * been done or is about to be done in the after bridge callback
+		 */
+		ao2_unlink(app_controls, control);
+		ao2_ref(wrapper, -1);
+	}
+}
+
 struct ast_channel *stasis_app_bridge_playback_channel_find(struct ast_bridge *bridge)
 {
 	struct stasis_app_bridge_channel_wrapper *playback_wrapper;