diff --git a/include/asterisk/bridge_channel_internal.h b/include/asterisk/bridge_channel_internal.h
index 09a447d616f1614eed3130d395e1343b7d2fa238..b5a3a8de2fe48b14c79fc2cd7f23f95e35848c50 100644
--- a/include/asterisk/bridge_channel_internal.h
+++ b/include/asterisk/bridge_channel_internal.h
@@ -107,6 +107,9 @@ void bridge_channel_settle_owed_events(struct ast_bridge *orig_bridge, struct as
  *
  * \retval 0 on success.
  * \retval -1 on failure.  The channel did not get pushed.
+ *
+ * \note On failure the caller must call
+ * ast_bridge_features_remove(bridge_channel->features, AST_BRIDGE_HOOK_REMOVE_ON_PULL);
  */
 int bridge_channel_internal_push(struct ast_bridge_channel *bridge_channel);
 
diff --git a/main/bridge.c b/main/bridge.c
index feeb564d4cd336d76636104beba4237351d6827f..a7b61847d215a95504f679efaab8eb90cffce9f0 100644
--- a/main/bridge.c
+++ b/main/bridge.c
@@ -1791,6 +1791,8 @@ void bridge_do_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridg
 		bridge_channel_change_bridge(bridge_channel, dst_bridge);
 
 		if (bridge_channel_internal_push(bridge_channel)) {
+			ast_bridge_features_remove(bridge_channel->features,
+				AST_BRIDGE_HOOK_REMOVE_ON_PULL);
 			ast_bridge_channel_leave_bridge(bridge_channel,
 				BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, bridge_channel->bridge->cause);
 		}
@@ -2036,11 +2038,15 @@ int bridge_do_move(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bri
 
 	if (bridge_channel_internal_push(bridge_channel)) {
 		/* Try to put the channel back into the original bridge. */
+		ast_bridge_features_remove(bridge_channel->features,
+			AST_BRIDGE_HOOK_REMOVE_ON_PULL);
 		if (attempt_recovery && was_in_bridge) {
 			/* Point back to original bridge. */
 			bridge_channel_change_bridge(bridge_channel, orig_bridge);
 
 			if (bridge_channel_internal_push(bridge_channel)) {
+				ast_bridge_features_remove(bridge_channel->features,
+					AST_BRIDGE_HOOK_REMOVE_ON_PULL);
 				ast_bridge_channel_leave_bridge(bridge_channel,
 					BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, bridge_channel->bridge->cause);
 				bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
diff --git a/main/bridge_channel.c b/main/bridge_channel.c
index f8277384fbee939cbfe214904e3185d47aea3cbd..9256a75d026ce51496a84f4fc2b35b26a92a7530 100644
--- a/main/bridge_channel.c
+++ b/main/bridge_channel.c
@@ -1566,7 +1566,6 @@ int bridge_channel_internal_push(struct ast_bridge_channel *bridge_channel)
 		|| ast_bridge_channel_establish_roles(bridge_channel)) {
 		ast_debug(1, "Bridge %s: pushing %p(%s) into bridge failed\n",
 			bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
-		ast_bridge_features_remove(bridge_channel->features, AST_BRIDGE_HOOK_REMOVE_ON_PULL);
 		return -1;
 	}
 	bridge_channel->in_bridge = 1;
@@ -1969,8 +1968,7 @@ int bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel)
 	 */
 	ast_bridge_lock(bridge_channel->bridge);
 
-	/* Make sure we're still good to be put into a bridge
-	 */
+	/* Make sure we're still good to be put into a bridge */
 	ast_channel_lock(bridge_channel->chan);
 	if (ast_channel_internal_bridge(bridge_channel->chan)
 		|| ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_ZOMBIE)) {
@@ -1993,8 +1991,14 @@ int bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel)
 	}
 
 	if (bridge_channel_internal_push(bridge_channel)) {
-		ast_bridge_channel_leave_bridge(bridge_channel,
-			BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, bridge_channel->bridge->cause);
+		int cause = bridge_channel->bridge->cause;
+
+		ast_bridge_unlock(bridge_channel->bridge);
+		ast_bridge_channel_kick(bridge_channel, cause);
+		ast_bridge_channel_lock_bridge(bridge_channel);
+		ast_bridge_features_remove(bridge_channel->features,
+			AST_BRIDGE_HOOK_REMOVE_ON_PULL);
+		bridge_channel_dissolve_check(bridge_channel);
 		res = -1;
 	}
 	bridge_reconfigured(bridge_channel->bridge, !bridge_channel->inhibit_colp);