diff --git a/include/asterisk/config.h b/include/asterisk/config.h
index 555269546a8324bed99f9213da3709e029603cce..8a375e526a240797316299f8b92670810c8265dc 100644
--- a/include/asterisk/config.h
+++ b/include/asterisk/config.h
@@ -334,6 +334,23 @@ const char *ast_variable_find(const struct ast_category *category, const char *v
  */
 const char *ast_variable_find_in_list(const struct ast_variable *list, const char *variable);
 
+/*!
+ * \brief Gets the LAST occurrence of a variable from a variable list
+ *
+ * \param list The ast_variable list to search
+ * \param variable The name of the ast_variable you wish to fetch data for
+ *
+ * \details
+ * Iterates over a given ast_variable list to search for the last occurrence of an
+ * ast_variable entry with a name attribute matching the given name (variable).
+ * This is useful if the list has duplicate entries (such as in cases where entries
+ * are created by a template)
+ *
+ * \retval The variable value on success
+ * \retval NULL if unable to find it.
+ */
+const char *ast_variable_find_last_in_list(const struct ast_variable *list, const char *variable);
+
 /*!
  * \brief Retrieve a category if it exists
  *
diff --git a/main/config.c b/main/config.c
index daccae535bf5f7451af3879f70add14f812d7ae4..f59e12164d20839c37175669a36dc96cd41fc68c 100644
--- a/main/config.c
+++ b/main/config.c
@@ -735,6 +735,19 @@ const char *ast_variable_find_in_list(const struct ast_variable *list, const cha
 	return NULL;
 }
 
+const char *ast_variable_find_last_in_list(const struct ast_variable *list, const char *variable)
+{
+	const struct ast_variable *v;
+	const char *found = NULL;
+
+	for (v = list; v; v = v->next) {
+		if (!strcasecmp(variable, v->name)) {
+			found = v->value;
+		}
+	}
+	return found;
+}
+
 static struct ast_variable *variable_clone(const struct ast_variable *old)
 {
 	struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
diff --git a/res/res_pjsip_config_wizard.c b/res/res_pjsip_config_wizard.c
index d6d5d5bcb07f5336df2b7471aea6c7b0f0d23a12..39d3c3f64657498d65fe3460fdc261059f97e845 100644
--- a/res/res_pjsip_config_wizard.c
+++ b/res/res_pjsip_config_wizard.c
@@ -334,10 +334,10 @@ static void *create_object(const struct ast_sorcery *sorcery,
 	return obj;
 }
 
-/*! \brief Finds a variable in a list and tests it */
+/*! \brief Finds the last variable in a list and tests it */
 static int is_variable_true(struct ast_variable *vars, const char *name)
 {
-	return ast_true(ast_variable_find_in_list(vars, name));
+	return ast_true(ast_variable_find_last_in_list(vars, name));
 }
 
 /*! \brief Appends a variable to the end of an existing list */
@@ -539,7 +539,7 @@ static int handle_auth(const struct ast_sorcery *sorcery, struct object_type_wiz
 	}
 
 	if (is_variable_true(wizvars, test_variable)) {
-		if (!ast_variable_find_in_list(vars, "username")) {
+		if (!ast_variable_find_last_in_list(vars, "username")) {
 			ast_log(LOG_ERROR,
 				"Wizard '%s' must have '%s_auth/username' if it %s.\n", id, direction, test_variable);
 			return -1;
@@ -557,7 +557,7 @@ static int handle_auth(const struct ast_sorcery *sorcery, struct object_type_wiz
 	variable_list_append_return(&vars, "@pjsip_wizard", id);
 
 	/* If the user set auth_type, don't override it. */
-	if (!ast_variable_find_in_list(vars, "auth_type")) {
+	if (!ast_variable_find_last_in_list(vars, "auth_type")) {
 		variable_list_append_return(&vars, "auth_type", "userpass");
 	}
 
@@ -599,8 +599,8 @@ static int handle_aor(const struct ast_sorcery *sorcery, struct object_type_wiza
 	variable_list_append(&vars, "@pjsip_wizard", id);
 
 	/* If the user explicitly specified an aor/contact, don't use remote hosts. */
-	if (!ast_variable_find_in_list(vars, "contact")) {
-		if (!(contact_pattern = ast_variable_find_in_list(wizvars, "contact_pattern"))) {
+	if (!ast_variable_find_last_in_list(vars, "contact")) {
+		if (!(contact_pattern = ast_variable_find_last_in_list(wizvars, "contact_pattern"))) {
 			contact_pattern = "sip:${REMOTE_HOST}";
 		}
 
@@ -645,10 +645,10 @@ static int handle_endpoint(const struct ast_sorcery *sorcery, struct object_type
 	struct ast_variable *wizvars = ast_category_first(wiz);
 	struct ast_sorcery_object *obj = NULL;
 	const char *id = ast_category_get_name(wiz);
-	const char *transport = ast_variable_find_in_list(wizvars, "transport");
-	const char *hint_context = hint_context = ast_variable_find_in_list(wizvars, "hint_context");
-	const char *hint_exten = ast_variable_find_in_list(wizvars, "hint_exten");
-	const char *hint_application= ast_variable_find_in_list(wizvars, "hint_application");
+	const char *transport = ast_variable_find_last_in_list(wizvars, "transport");
+	const char *hint_context = hint_context = ast_variable_find_last_in_list(wizvars, "hint_context");
+	const char *hint_exten = ast_variable_find_last_in_list(wizvars, "hint_exten");
+	const char *hint_application= ast_variable_find_last_in_list(wizvars, "hint_application");
 	char new_id[strlen(id) + MAX_ID_SUFFIX];
 	RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "endpoint/"), ast_variables_destroy);
 
@@ -656,7 +656,7 @@ static int handle_endpoint(const struct ast_sorcery *sorcery, struct object_type
 	variable_list_append_return(&vars, "aors", id);
 
 	if (ast_strlen_zero(hint_context)) {
-		hint_context = ast_variable_find_in_list(vars, "context");
+		hint_context = ast_variable_find_last_in_list(vars, "context");
 	}
 
 	if (ast_strlen_zero(hint_context)) {
@@ -737,7 +737,7 @@ static int handle_identify(const struct ast_sorcery *sorcery, struct object_type
 	variable_list_append_return(&vars, "endpoint", id);
 	variable_list_append_return(&vars, "@pjsip_wizard", id);
 
-	if (!ast_variable_find_in_list(vars, "match")) {
+	if (!ast_variable_find_last_in_list(vars, "match")) {
 		for (host_counter = 0; host_counter < host_count; host_counter++) {
 			char *rhost = AST_VECTOR_GET(remote_hosts_vector, host_counter);
 			char host[strlen(rhost) + 1];
@@ -787,7 +787,7 @@ static int handle_phoneprov(const struct ast_sorcery *sorcery, struct object_typ
 		return 0;
 	}
 
-	if (!ast_variable_find_in_list(wizvars, "phoneprov/MAC")) {
+	if (!ast_variable_find_last_in_list(wizvars, "phoneprov/MAC")) {
 		ast_log(LOG_ERROR,
 			"Wizard '%s' must have 'phoneprov/MAC' if it has_phoneprov.\n", id);
 		return -1;
@@ -834,7 +834,7 @@ static int handle_registrations(const struct ast_sorcery *sorcery, struct object
 	const char *id = ast_category_get_name(wiz);
 	const char *server_uri_pattern;
 	const char *client_uri_pattern;
-	const char *transport = ast_variable_find_in_list(wizvars, "transport");
+	const char *transport = ast_variable_find_last_in_list(wizvars, "transport");
 	const char *username;
 	char new_id[strlen(id) + MAX_ID_SUFFIX];
 	int host_count = AST_VECTOR_SIZE(remote_hosts_vector);
@@ -871,16 +871,16 @@ static int handle_registrations(const struct ast_sorcery *sorcery, struct object
 
 	variable_list_append_return(&vars, "@pjsip_wizard", id);
 
-	if (!(server_uri_pattern = ast_variable_find_in_list(wizvars, "server_uri_pattern"))) {
+	if (!(server_uri_pattern = ast_variable_find_last_in_list(wizvars, "server_uri_pattern"))) {
 		server_uri_pattern = "sip:${REMOTE_HOST}";
 	}
 
-	if (!(client_uri_pattern = ast_variable_find_in_list(wizvars, "client_uri_pattern"))) {
+	if (!(client_uri_pattern = ast_variable_find_last_in_list(wizvars, "client_uri_pattern"))) {
 		client_uri_pattern = "sip:${USERNAME}@${REMOTE_HOST}";
 	}
 
 	if(is_variable_true(wizvars, "sends_auth")) {
-		username = ast_variable_find_in_list(wizvars, "outbound_auth/username");
+		username = ast_variable_find_last_in_list(wizvars, "outbound_auth/username");
 	} else {
 		username = id;
 	}
@@ -958,7 +958,7 @@ static int wizard_apply_handler(const struct ast_sorcery *sorcery, struct object
 	int rc = -1;
 
 	AST_VECTOR_INIT(&remote_hosts_vector, 16);
-	remote_hosts = ast_variable_find_in_list(wizvars, "remote_hosts");
+	remote_hosts = ast_variable_find_last_in_list(wizvars, "remote_hosts");
 
 	if (!ast_strlen_zero(remote_hosts)) {
 		char *host;
diff --git a/tests/test_config.c b/tests/test_config.c
index df618f9f77b69a91759de3bae7f062d242dee067..b9935dc79bcdd48d53348355e231b66252f33e43 100644
--- a/tests/test_config.c
+++ b/tests/test_config.c
@@ -234,6 +234,7 @@ AST_TEST_DEFINE(config_basic_ops)
 	struct ast_config *cfg = NULL;
 	struct ast_category *cat = NULL;
 	struct ast_variable *var;
+	struct ast_variable *varlist;
 	char temp[32];
 	const char *cat_name;
 	const char *var_value;
@@ -537,6 +538,22 @@ AST_TEST_DEFINE(config_basic_ops)
 		goto out;
 	}
 
+	varlist = ast_variable_new("name1", "value1", "");
+	ast_variable_list_append_hint(&varlist, NULL, ast_variable_new("name1", "value2", ""));
+	ast_variable_list_append_hint(&varlist, NULL, ast_variable_new("name1", "value3", ""));
+
+	var_value = ast_variable_find_in_list(varlist, "name1");
+	if (strcmp(var_value, "value1") != 0) {
+		ast_test_status_update(test, "Wrong variable retrieved %s.\n", var_value);
+		goto out;
+	}
+
+	var_value = ast_variable_find_last_in_list(varlist, "name1");
+	if (strcmp(var_value, "value3") != 0) {
+		ast_test_status_update(test, "Wrong variable retrieved %s.\n", var_value);
+		goto out;
+	}
+
 	res = AST_TEST_PASS;
 
 out: