diff --git a/include/asterisk/features_config.h b/include/asterisk/features_config.h
index b15759ba6c4c649979d445ac0f12f7361cb798f7..baaff183b3061087ced7edd77021d6ed896ba648 100644
--- a/include/asterisk/features_config.h
+++ b/include/asterisk/features_config.h
@@ -101,6 +101,21 @@ struct ast_features_xfer_config {
  */
 struct ast_features_xfer_config *ast_get_chan_features_xfer_config(struct ast_channel *chan);
 
+/*!
+ * \brief Get the transfer configuration option xferfailsound
+ *
+ * \note The channel should be locked before calling this function.
+ * \note The returned value has to be freed.
+ *
+ * If no channel is provided, then option is pulled from the global
+ * transfer configuration.
+ *
+ * \param chan The channel to get configuration options for
+ * \retval NULL Failed to get configuration
+ * \retval non-NULL The xferfailsound
+ */
+char *ast_get_chan_features_xferfailsound(struct ast_channel *chan);
+
 /*!
  * \brief Configuration relating to call pickup
  */
diff --git a/main/bridge_basic.c b/main/bridge_basic.c
index cd19915205a95b3554622e4b1d83f317a336742b..5d8ee49d06ca5fdd6a9e1b50a841b9c5ddf89951 100644
--- a/main/bridge_basic.c
+++ b/main/bridge_basic.c
@@ -1296,8 +1296,6 @@ struct attended_transfer_properties {
 		AST_STRING_FIELD(exten);
 		/*! Context of transfer target */
 		AST_STRING_FIELD(context);
-		/*! Sound to play on failure */
-		AST_STRING_FIELD(failsound);
 		/*! Sound to play when transfer completes */
 		AST_STRING_FIELD(xfersound);
 		/*! The channel technology of the transferer channel */
@@ -1421,12 +1419,21 @@ static struct attended_transfer_properties *attended_transfer_properties_alloc(
 	struct ast_flags *transferer_features;
 
 	props = ao2_alloc(sizeof(*props), attended_transfer_properties_destructor);
-	if (!props || ast_string_field_init(props, 64)) {
+	if (!props) {
+		ast_log(LOG_ERROR, "Unable to create props - channel %s, context %s\n",
+			ast_channel_name(transferer), context);
 		return NULL;
 	}
 
 	ast_cond_init(&props->cond, NULL);
 
+	if (ast_string_field_init(props, 64)) {
+		ast_log(LOG_ERROR, "Unable to initialize prop fields - channel %s, context %s\n",
+			ast_channel_name(transferer), context);
+		ao2_ref(props, -1);
+		return NULL;
+	}
+
 	props->target_framehook_id = -1;
 	props->transferer = ast_channel_ref(transferer);
 
@@ -1447,7 +1454,6 @@ static struct attended_transfer_properties *attended_transfer_properties_alloc(
 	props->atxfernoanswertimeout = xfer_cfg->atxfernoanswertimeout;
 	props->atxferloopdelay = xfer_cfg->atxferloopdelay;
 	ast_string_field_set(props, context, get_transfer_context(transferer, context));
-	ast_string_field_set(props, failsound, xfer_cfg->xferfailsound);
 	ast_string_field_set(props, xfersound, xfer_cfg->xfersound);
 	ao2_ref(xfer_cfg, -1);
 
@@ -1707,6 +1713,44 @@ static void play_sound(struct ast_channel *chan, const char *sound)
 	}
 }
 
+/*!
+ * \brief Helper method to play a fail sound on a channel in a bridge
+ *
+ * \param chan The channel to play the fail sound to
+ */
+static void play_failsound(struct ast_channel *chan)
+{
+	char *sound;
+
+	ast_channel_lock(chan);
+	sound = ast_get_chan_features_xferfailsound(chan);
+	ast_channel_unlock(chan);
+
+	if (sound) {
+		play_sound(chan, sound);
+		ast_free(sound);
+	}
+}
+
+/*!
+ * \brief Helper method to stream a fail sound on a channel
+ *
+ * \param chan The channel to stream the fail sound to
+ */
+static void stream_failsound(struct ast_channel *chan)
+{
+	char *sound;
+
+	ast_channel_lock(chan);
+	sound = ast_get_chan_features_xferfailsound(chan);
+	ast_channel_unlock(chan);
+
+	if (sound) {
+		ast_stream_and_wait(chan, sound, AST_DIGIT_NONE);
+		ast_free(sound);
+	}
+}
+
 /*!
  * \brief Helper method to place a channel in a bridge on hold
  */
@@ -2049,7 +2093,7 @@ static enum attended_transfer_state calling_target_exit(struct attended_transfer
 {
 	switch (stimulus) {
 	case STIMULUS_TRANSFEREE_HANGUP:
-		play_sound(props->transferer, props->failsound);
+		play_failsound(props->transferer);
 		publish_transfer_fail(props);
 		return TRANSFER_FAIL;
 	case STIMULUS_DTMF_ATXFER_COMPLETE:
@@ -2061,7 +2105,7 @@ static enum attended_transfer_state calling_target_exit(struct attended_transfer
 	case STIMULUS_TRANSFER_TARGET_HANGUP:
 	case STIMULUS_TIMEOUT:
 	case STIMULUS_DTMF_ATXFER_ABORT:
-		play_sound(props->transferer, props->failsound);
+		play_failsound(props->transferer);
 		return TRANSFER_REBRIDGE;
 	case STIMULUS_DTMF_ATXFER_THREEWAY:
 		bridge_unhold(props->transferee_bridge);
@@ -2090,7 +2134,7 @@ static enum attended_transfer_state hesitant_exit(struct attended_transfer_prope
 {
 	switch (stimulus) {
 	case STIMULUS_TRANSFEREE_HANGUP:
-		play_sound(props->transferer, props->failsound);
+		play_failsound(props->transferer);
 		publish_transfer_fail(props);
 		return TRANSFER_FAIL;
 	case STIMULUS_DTMF_ATXFER_COMPLETE:
@@ -2101,7 +2145,7 @@ static enum attended_transfer_state hesitant_exit(struct attended_transfer_prope
 	case STIMULUS_TRANSFER_TARGET_HANGUP:
 	case STIMULUS_TIMEOUT:
 	case STIMULUS_DTMF_ATXFER_ABORT:
-		play_sound(props->transferer, props->failsound);
+		play_failsound(props->transferer);
 		return TRANSFER_RESUME;
 	case STIMULUS_DTMF_ATXFER_THREEWAY:
 		return TRANSFER_THREEWAY;
@@ -2163,7 +2207,7 @@ static enum attended_transfer_state consulting_exit(struct attended_transfer_pro
 		 * a sound to the transferer to indicate the transferee is gone.
 		 */
 		bridge_basic_change_personality(props->target_bridge, BRIDGE_BASIC_PERSONALITY_NORMAL, NULL);
-		play_sound(props->transferer, props->failsound);
+		play_failsound(props->transferer);
 		ast_bridge_merge_inhibit(props->target_bridge, -1);
 		/* These next two lines are here to ensure that our reference to the target bridge
 		 * is cleaned up properly and that the target bridge is not destroyed when the
@@ -2179,7 +2223,7 @@ static enum attended_transfer_state consulting_exit(struct attended_transfer_pro
 		return TRANSFER_COMPLETE;
 	case STIMULUS_TRANSFER_TARGET_HANGUP:
 	case STIMULUS_DTMF_ATXFER_ABORT:
-		play_sound(props->transferer, props->failsound);
+		play_failsound(props->transferer);
 		return TRANSFER_REBRIDGE;
 	case STIMULUS_DTMF_ATXFER_THREEWAY:
 		bridge_unhold(props->transferee_bridge);
@@ -2211,7 +2255,7 @@ static enum attended_transfer_state double_checking_exit(struct attended_transfe
 {
 	switch (stimulus) {
 	case STIMULUS_TRANSFEREE_HANGUP:
-		play_sound(props->transferer, props->failsound);
+		play_failsound(props->transferer);
 		publish_transfer_fail(props);
 		return TRANSFER_FAIL;
 	case STIMULUS_TRANSFERER_HANGUP:
@@ -2221,7 +2265,7 @@ static enum attended_transfer_state double_checking_exit(struct attended_transfe
 		return TRANSFER_COMPLETE;
 	case STIMULUS_TRANSFER_TARGET_HANGUP:
 	case STIMULUS_DTMF_ATXFER_ABORT:
-		play_sound(props->transferer, props->failsound);
+		play_failsound(props->transferer);
 		return TRANSFER_RESUME;
 	case STIMULUS_DTMF_ATXFER_THREEWAY:
 		bridge_unhold(props->target_bridge);
@@ -3295,7 +3339,7 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
 	props->transfer_target = dial_transfer(bridge_channel->chan, destination);
 	if (!props->transfer_target) {
 		ast_log(LOG_ERROR, "Unable to request outbound channel for attended transfer target.\n");
-		ast_stream_and_wait(props->transferer, props->failsound, AST_DIGIT_NONE);
+		stream_failsound(props->transferer);
 		ast_bridge_channel_write_unhold(bridge_channel);
 		attended_transfer_properties_shutdown(props);
 		return 0;
@@ -3306,7 +3350,7 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
 	props->target_bridge = ast_bridge_basic_new();
 	if (!props->target_bridge) {
 		ast_log(LOG_ERROR, "Unable to create bridge for attended transfer target.\n");
-		ast_stream_and_wait(props->transferer, props->failsound, AST_DIGIT_NONE);
+		stream_failsound(props->transferer);
 		ast_bridge_channel_write_unhold(bridge_channel);
 		ast_hangup(props->transfer_target);
 		props->transfer_target = NULL;
@@ -3317,7 +3361,7 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
 
 	if (attach_framehook(props, props->transfer_target)) {
 		ast_log(LOG_ERROR, "Unable to attach framehook to transfer target.\n");
-		ast_stream_and_wait(props->transferer, props->failsound, AST_DIGIT_NONE);
+		stream_failsound(props->transferer);
 		ast_bridge_channel_write_unhold(bridge_channel);
 		ast_hangup(props->transfer_target);
 		props->transfer_target = NULL;
@@ -3332,7 +3376,7 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
 
 	if (ast_call(props->transfer_target, destination, 0)) {
 		ast_log(LOG_ERROR, "Unable to place outbound call to transfer target.\n");
-		ast_stream_and_wait(bridge_channel->chan, props->failsound, AST_DIGIT_NONE);
+		stream_failsound(props->transferer);
 		ast_bridge_channel_write_unhold(bridge_channel);
 		ast_hangup(props->transfer_target);
 		props->transfer_target = NULL;
@@ -3348,7 +3392,7 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
 	if (ast_bridge_impart(props->target_bridge, props->transfer_target, NULL, NULL,
 		AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {
 		ast_log(LOG_ERROR, "Unable to place transfer target into bridge.\n");
-		ast_stream_and_wait(bridge_channel->chan, props->failsound, AST_DIGIT_NONE);
+		stream_failsound(props->transferer);
 		ast_bridge_channel_write_unhold(bridge_channel);
 		ast_hangup(props->transfer_target);
 		props->transfer_target = NULL;
@@ -3358,7 +3402,7 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
 
 	if (ast_pthread_create_detached(&thread, NULL, attended_transfer_monitor_thread, props)) {
 		ast_log(LOG_ERROR, "Unable to create monitoring thread for attended transfer.\n");
-		ast_stream_and_wait(bridge_channel->chan, props->failsound, AST_DIGIT_NONE);
+		stream_failsound(props->transferer);
 		ast_bridge_channel_write_unhold(bridge_channel);
 		attended_transfer_properties_shutdown(props);
 		return 0;
diff --git a/main/features_config.c b/main/features_config.c
index 3db1a780a4afdc6fa063431a41b33892f7e4df05..58ccb959b213eb28e975d78c035aad82abda1f86 100644
--- a/main/features_config.c
+++ b/main/features_config.c
@@ -1158,6 +1158,21 @@ struct ast_features_xfer_config *ast_get_chan_features_xfer_config(struct ast_ch
 	return cfg->global->xfer;
 }
 
+char *ast_get_chan_features_xferfailsound(struct ast_channel *chan)
+{
+	char *res;
+	struct ast_features_xfer_config *cfg = ast_get_chan_features_xfer_config(chan);
+
+	if (!cfg) {
+		return NULL;
+	}
+
+	res = ast_strdup(cfg->xferfailsound);
+	ao2_ref(cfg, -1);
+
+	return res;
+}
+
 struct ast_features_pickup_config *ast_get_chan_features_pickup_config(struct ast_channel *chan)
 {
 	RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);