diff --git a/addons/cdr_mysql.c b/addons/cdr_mysql.c
index 0878950e112660c90716a208b86419e497742a18..f8f4192acde08f0901dd27c416ef0fc503a1726e 100644
--- a/addons/cdr_mysql.c
+++ b/addons/cdr_mysql.c
@@ -351,9 +351,20 @@ db_reconnect:
 	return 0;
 }
 
+static void free_strings(void)
+{
+	struct unload_string *us;
+
+	AST_LIST_LOCK(&unload_strings);
+	while ((us = AST_LIST_REMOVE_HEAD(&unload_strings, entry))) {
+		ast_free(us->str);
+		ast_free(us);
+	}
+	AST_LIST_UNLOCK(&unload_strings);
+}
+
 static int my_unload_module(int reload)
 { 
-	struct unload_string *us;
 	struct column *entry;
 
 	ast_cli_unregister_multiple(cdr_mysql_status_cli, sizeof(cdr_mysql_status_cli) / sizeof(struct ast_cli_entry));
@@ -364,12 +375,7 @@ static int my_unload_module(int reload)
 		records = 0;
 	}
 
-	AST_LIST_LOCK(&unload_strings);
-	while ((us = AST_LIST_REMOVE_HEAD(&unload_strings, entry))) {
-		ast_free(us->str);
-		ast_free(us);
-	}
-	AST_LIST_UNLOCK(&unload_strings);
+	free_strings();
 
 	if (!reload) {
 		AST_RWLIST_WRLOCK(&columns);
@@ -505,13 +511,16 @@ static int my_load_module(int reload)
 	} else {
 		calldate_compat = 0;
 	}
+	ast_free(compat);
 
 	if (res < 0) {
 		if (reload) {
 			AST_RWLIST_UNLOCK(&columns);
 		}
 		ast_config_destroy(cfg);
-		return AST_MODULE_LOAD_FAILURE;
+		free_strings();
+
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Check for any aliases */
@@ -582,7 +591,9 @@ static int my_load_module(int reload)
 			connected = 0;
 			AST_RWLIST_UNLOCK(&columns);
 			ast_config_destroy(cfg);
-			return AST_MODULE_LOAD_FAILURE;
+			free_strings();
+
+			return AST_MODULE_LOAD_DECLINE;
 		}
 
 		if (!(result = mysql_store_result(&mysql))) {
@@ -591,7 +602,9 @@ static int my_load_module(int reload)
 			connected = 0;
 			AST_RWLIST_UNLOCK(&columns);
 			ast_config_destroy(cfg);
-			return AST_MODULE_LOAD_FAILURE;
+			free_strings();
+
+			return AST_MODULE_LOAD_DECLINE;
 		}
 
 		while ((row = mysql_fetch_row(result))) {
@@ -657,7 +670,8 @@ static int my_load_module(int reload)
 	AST_RWLIST_UNLOCK(&columns);
 	ast_config_destroy(cfg);
 	if (res < 0) {
-		return AST_MODULE_LOAD_FAILURE;
+		my_unload_module(0);
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!reload) {
@@ -671,7 +685,12 @@ static int my_load_module(int reload)
 		res = ast_cli_register_multiple(cdr_mysql_status_cli, sizeof(cdr_mysql_status_cli) / sizeof(struct ast_cli_entry));
 	}
 
-	return res;
+	if (res) {
+		my_unload_module(0);
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int load_module(void)
diff --git a/addons/chan_mobile.c b/addons/chan_mobile.c
index bd39bee6431261b4bc2e6a8137603134c010f761..8f04af7530243289eadc0b05ff9d30edbebd9360 100644
--- a/addons/chan_mobile.c
+++ b/addons/chan_mobile.c
@@ -4704,9 +4704,13 @@ static int load_module(void)
 	ast_format_cap_append(mbl_tech.capabilities, DEVICE_FRAME_FORMAT, 0);
 	/* Check if we have Bluetooth, no point loading otherwise... */
 	dev_id = hci_get_route(NULL);
+
 	s = hci_open_dev(dev_id);
 	if (dev_id < 0 || s < 0) {
 		ast_log(LOG_ERROR, "No Bluetooth devices found. Not loading module.\n");
+		ao2_ref(mbl_tech.capabilities, -1);
+		mbl_tech.capabilities = NULL;
+		hci_close_dev(s);
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
@@ -4714,6 +4718,8 @@ static int load_module(void)
 
 	if (mbl_load_config()) {
 		ast_log(LOG_ERROR, "Errors reading config file %s. Not loading module.\n", MBL_CONFIG);
+		ao2_ref(mbl_tech.capabilities, -1);
+		mbl_tech.capabilities = NULL;
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
@@ -4738,10 +4744,9 @@ static int load_module(void)
 	return AST_MODULE_LOAD_SUCCESS;
 
 e_cleanup:
-	if (sdp_session)
-		sdp_close(sdp_session);
+	unload_module();
 
-	return AST_MODULE_LOAD_FAILURE;
+	return AST_MODULE_LOAD_DECLINE;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Bluetooth Mobile Device Channel Driver",
diff --git a/apps/app_adsiprog.c b/apps/app_adsiprog.c
index 9d73702f6a0444442f14fd157c2e11f5a990cf0f..6d485d6fb7a3f2b8fe935bbc157a99e408bc5f55 100644
--- a/apps/app_adsiprog.c
+++ b/apps/app_adsiprog.c
@@ -1605,7 +1605,7 @@ static int unload_module(void)
 static int load_module(void)
 {
 	if (ast_register_application_xml(app, adsi_exec))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/apps/app_agent_pool.c b/apps/app_agent_pool.c
index 4563b58a09afb6578ca3fad517cf2c1a571cc88b..2e0c8e880273f560c12db7f379e5b2bee333ba11 100644
--- a/apps/app_agent_pool.c
+++ b/apps/app_agent_pool.c
@@ -2653,7 +2653,7 @@ static int load_module(void)
 	agents = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_MUTEX,
 		AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, agent_pvt_sort_cmp, agent_pvt_cmp);
 	if (!agents) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Init agent holding bridge v_table. */
@@ -2677,8 +2677,9 @@ static int load_module(void)
 	res |= ast_register_application_xml(app_agent_request, agent_request_exec);
 
 	if (res) {
+		ast_log(LOG_ERROR, "Unable to register application. Not loading module.\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (load_config()) {
diff --git a/apps/app_alarmreceiver.c b/apps/app_alarmreceiver.c
index 2169617acb3605f37cd36af76df2a30eb95d1ee5..07885d2bf19fb24efd54330b81f89960f2aa0623 100644
--- a/apps/app_alarmreceiver.c
+++ b/apps/app_alarmreceiver.c
@@ -975,7 +975,7 @@ static int load_module(void)
 {
 	if (load_config(0)) {
 		if (ast_register_application_xml(app, alarmreceiver_exec)) {
-			return AST_MODULE_LOAD_FAILURE;
+			return AST_MODULE_LOAD_DECLINE;
 		}
 		return AST_MODULE_LOAD_SUCCESS;
 	}
diff --git a/apps/app_authenticate.c b/apps/app_authenticate.c
index f58ed362619e1cbed672bfe912c8e75d2cfb5600..e0ad4a089118af9e1907407eeeda3c07572b5c7c 100644
--- a/apps/app_authenticate.c
+++ b/apps/app_authenticate.c
@@ -270,7 +270,7 @@ static int unload_module(void)
 static int load_module(void)
 {
 	if (ast_register_application_xml(app, auth_exec))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/apps/app_cdr.c b/apps/app_cdr.c
index 17dea431db2c5c48bcabd0ddde24713144fa6432..1500c89f6c2379a1fc0fcdbc2bacee440783f4c9 100644
--- a/apps/app_cdr.c
+++ b/apps/app_cdr.c
@@ -249,7 +249,7 @@ static int load_module(void)
 	int res = 0;
 
 	if (!router) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	res |= STASIS_MESSAGE_TYPE_INIT(appcdr_message_type);
@@ -259,7 +259,8 @@ static int load_module(void)
 	                                 appcdr_callback, NULL);
 
 	if (res) {
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c
index 5ec20ddb9932d4d98aac863ef009316a9dd4f8f5..a9f917b9a974bfc73b80007837f08dd2d752158e 100644
--- a/apps/app_confbridge.c
+++ b/apps/app_confbridge.c
@@ -3955,7 +3955,7 @@ static int load_module(void)
 	if (register_channel_tech(conf_record_get_tech())
 		|| register_channel_tech(conf_announce_get_tech())) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Create a container to hold the conference bridges */
@@ -3963,7 +3963,7 @@ static int load_module(void)
 		conference_bridge_hash_cb, conference_bridge_cmp_cb);
 	if (!conference_bridges) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Setup manager stasis subscriptions */
@@ -3988,7 +3988,7 @@ static int load_module(void)
 	res |= ast_manager_register_xml("ConfbridgeSetSingleVideoSrc", EVENT_FLAG_CALL, action_confbridgesetsinglevideosrc);
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/apps/app_dahdiras.c b/apps/app_dahdiras.c
index 6eaa1bd2236b21d500e370fa52024a8fc3fa3121..10c2962c6908a394a6b9cec1f3e4fdf2d5a99491 100644
--- a/apps/app_dahdiras.c
+++ b/apps/app_dahdiras.c
@@ -223,7 +223,7 @@ static int unload_module(void)
 
 static int load_module(void)
 {
-	return ((ast_register_application_xml(app, dahdiras_exec)) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS);
+	return ((ast_register_application_xml(app, dahdiras_exec)) ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS);
 }
 
 AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "DAHDI ISDN Remote Access Server");
diff --git a/apps/app_forkcdr.c b/apps/app_forkcdr.c
index acd8982ef4f655724f5e4af192483b4a37423eaa..5946c5009b15b653d6b3752aa94adb5a534af3b2 100644
--- a/apps/app_forkcdr.c
+++ b/apps/app_forkcdr.c
@@ -199,7 +199,7 @@ static int load_module(void)
 	int res = 0;
 
 	if (!router) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	res |= STASIS_MESSAGE_TYPE_INIT(forkcdr_message_type);
@@ -208,7 +208,9 @@ static int load_module(void)
 	                                 forkcdr_callback, NULL);
 
 	if (res) {
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
diff --git a/apps/app_queue.c b/apps/app_queue.c
index ae2d645e9455280e2c3e36afebb2eccf6c53e37e..2389f0b131422d2e849c99d28010c5ede4536bab 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -8892,7 +8892,7 @@ static int reload_queue_rules(int reload)
 		if (!(new_rl = ast_calloc(1, sizeof(*new_rl)))) {
 			AST_LIST_UNLOCK(&rule_lists);
 			ast_config_destroy(cfg);
-			return AST_MODULE_LOAD_FAILURE;
+			return AST_MODULE_LOAD_DECLINE;
 		} else {
 			ast_copy_string(new_rl->name, rulecat, sizeof(new_rl->name));
 			AST_LIST_INSERT_TAIL(&rule_lists, new_rl, list);
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index aebaafaf362ae8f510a78d308da53e9ccbea3f54..de826704a76fb958d024e77425b6f027cf30bb07 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -14974,7 +14974,7 @@ static int load_module(void)
 	umask(my_umask);
 
 	if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* compute the location of the voicemail spool directory */
diff --git a/apps/app_zapateller.c b/apps/app_zapateller.c
index e876a70a8d778c4155b4a333d404a4cc98dcd7fc..f62f7bb50293051052fcd59247b039356f872310 100644
--- a/apps/app_zapateller.c
+++ b/apps/app_zapateller.c
@@ -132,7 +132,7 @@ static int unload_module(void)
 
 static int load_module(void)
 {
-	return ((ast_register_application_xml(app, zapateller_exec)) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS);
+	return ((ast_register_application_xml(app, zapateller_exec)) ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS);
 }
 
 AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "Block Telemarketers with Special Information Tone");
diff --git a/cdr/cdr_custom.c b/cdr/cdr_custom.c
index 7d8b9d82ec95e7fd55962a349044c96e648a8a72..fec20eaa8d2955c3067712ae9dc85f8461e347b4 100644
--- a/cdr/cdr_custom.c
+++ b/cdr/cdr_custom.c
@@ -203,7 +203,7 @@ static enum ast_module_load_result load_module(void)
 {
 	if (AST_RWLIST_WRLOCK(&sinks)) {
 		ast_log(LOG_ERROR, "Unable to lock sink list.  Load failed.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	load_config();
@@ -216,7 +216,7 @@ static int reload(void)
 {
 	if (AST_RWLIST_WRLOCK(&sinks)) {
 		ast_log(LOG_ERROR, "Unable to lock sink list.  Load failed.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	free_config();
diff --git a/cel/cel_custom.c b/cel/cel_custom.c
index d1655413f3a4373a14d2e68026c88599ad28c1c0..d05a1260c3c25d76cc65abc03a5322211f4ba2ad 100644
--- a/cel/cel_custom.c
+++ b/cel/cel_custom.c
@@ -191,14 +191,15 @@ static enum ast_module_load_result load_module(void)
 {
 	if (AST_RWLIST_WRLOCK(&sinks)) {
 		ast_log(LOG_ERROR, "Unable to lock sink list.  Load failed.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	load_config();
 	AST_RWLIST_UNLOCK(&sinks);
 
 	if (ast_cel_backend_register(CUSTOM_BACKEND_NAME, custom_log)) {
-		return AST_MODULE_LOAD_FAILURE;
+		free_config();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
@@ -207,7 +208,7 @@ static int reload(void)
 {
 	if (AST_RWLIST_WRLOCK(&sinks)) {
 		ast_log(LOG_ERROR, "Unable to lock sink list.  Load failed.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	free_config();
diff --git a/cel/cel_odbc.c b/cel/cel_odbc.c
index 2ab511418d0d5b3627ccf372fdf76830b8a5ed4a..a0cc6e33aaa0d496dd611bbf2ea8397ca390f58e 100644
--- a/cel/cel_odbc.c
+++ b/cel/cel_odbc.c
@@ -801,13 +801,14 @@ static int load_module(void)
 
 	if (AST_RWLIST_WRLOCK(&odbc_tables)) {
 		ast_log(LOG_ERROR, "Unable to lock column list.  Load failed.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	load_config();
 	AST_RWLIST_UNLOCK(&odbc_tables);
 	if (ast_cel_backend_register(ODBC_BACKEND_NAME, odbc_log)) {
 		ast_log(LOG_ERROR, "Unable to subscribe to CEL events\n");
-		return AST_MODULE_LOAD_FAILURE;
+		free_config();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
@@ -816,7 +817,7 @@ static int reload(void)
 {
 	if (AST_RWLIST_WRLOCK(&odbc_tables)) {
 		ast_log(LOG_ERROR, "Unable to lock column list.  Reload failed.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	free_config();
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c
index c50b5408e35552dec683c33461399ad38878ece7..c53c1a3449d7f948c9d4b4089abd5b62a7ddf771 100644
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -924,6 +924,26 @@ static struct ast_cli_entry cli_alsa[] = {
 	AST_CLI_DEFINE(console_mute, "Disable/Enable mic input"),
 };
 
+static int unload_module(void)
+{
+	ast_channel_unregister(&alsa_tech);
+	ast_cli_unregister_multiple(cli_alsa, ARRAY_LEN(cli_alsa));
+
+	if (alsa.icard)
+		snd_pcm_close(alsa.icard);
+	if (alsa.ocard)
+		snd_pcm_close(alsa.ocard);
+	if (alsa.owner)
+		ast_softhangup(alsa.owner, AST_SOFTHANGUP_APPUNLOAD);
+	if (alsa.owner)
+		return -1;
+
+	ao2_cleanup(alsa_tech.capabilities);
+	alsa_tech.capabilities = NULL;
+
+	return 0;
+}
+
 /*!
  * \brief Load the module
  *
@@ -994,12 +1014,16 @@ static int load_module(void)
 	if (soundcard_init() < 0) {
 		ast_verb(2, "No sound card detected -- console channel will be unavailable\n");
 		ast_verb(2, "Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf\n");
+		unload_module();
+
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_channel_register(&alsa_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class 'Console'\n");
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	ast_cli_register_multiple(cli_alsa, ARRAY_LEN(cli_alsa));
@@ -1007,26 +1031,6 @@ static int load_module(void)
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
-static int unload_module(void)
-{
-	ast_channel_unregister(&alsa_tech);
-	ast_cli_unregister_multiple(cli_alsa, ARRAY_LEN(cli_alsa));
-
-	if (alsa.icard)
-		snd_pcm_close(alsa.icard);
-	if (alsa.ocard)
-		snd_pcm_close(alsa.ocard);
-	if (alsa.owner)
-		ast_softhangup(alsa.owner, AST_SOFTHANGUP_APPUNLOAD);
-	if (alsa.owner)
-		return -1;
-
-	ao2_cleanup(alsa_tech.capabilities);
-	alsa_tech.capabilities = NULL;
-
-	return 0;
-}
-
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "ALSA Console Channel Driver",
 	.support_level = AST_MODULE_SUPPORT_EXTENDED,
 	.load = load_module,
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 97c80c83e30edc32f4a957932139981766b3861b..72fbe6e0c7c1887277e574bcfe322da3d64d360e 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -19530,11 +19530,11 @@ static int load_module(void)
 #endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
 
 	if (STASIS_MESSAGE_TYPE_INIT(dahdichannel_type)) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(dahdi_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append(dahdi_tech.capabilities, ast_format_slin, 0);
 	ast_format_cap_append(dahdi_tech.capabilities, ast_format_ulaw, 0);
@@ -19542,7 +19542,7 @@ static int load_module(void)
 
 	if (dahdi_native_load(&dahdi_tech)) {
 		ao2_ref(dahdi_tech.capabilities, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 #ifdef HAVE_PRI
@@ -19560,7 +19560,7 @@ static int load_module(void)
 	if (ast_cc_agent_register(&dahdi_pri_cc_agent_callbacks)
 		|| ast_cc_monitor_register(&dahdi_pri_cc_monitor_callbacks)) {
 		__unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 #endif	/* defined(HAVE_PRI_CCSS) */
 	if (sig_pri_load(
@@ -19571,7 +19571,7 @@ static int load_module(void)
 #endif	/* defined(HAVE_PRI_CCSS) */
 		)) {
 		__unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 #endif
 #if defined(HAVE_SS7)
@@ -19594,7 +19594,7 @@ static int load_module(void)
 	if (ast_channel_register(&dahdi_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class 'DAHDI'\n");
 		__unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 #ifdef HAVE_PRI
 	ast_cli_register_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli));
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 38dc5c00e59bc2a8fa50b750c5ddb5fc918f91b1..d15b55d725fe5cff88c88445c14c75a7deb582c5 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -14886,7 +14886,7 @@ container_fail:
 	if (calltoken_ignores) {
 		ao2_ref(calltoken_ignores, -1);
 	}
-	return AST_MODULE_LOAD_FAILURE;
+	return -1;
 }
 
 
@@ -15091,12 +15091,14 @@ static int load_module(void)
 	struct iax2_registry *reg = NULL;
 
 	if (!(iax2_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append_by_type(iax2_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);
 
 	if (load_objects()) {
-		return AST_MODULE_LOAD_FAILURE;
+		ao2_ref(iax2_tech.capabilities, -1);
+		iax2_tech.capabilities = NULL;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	memset(iaxs, 0, sizeof(iaxs));
@@ -15107,28 +15109,36 @@ static int load_module(void)
 
 	if (!(sched = ast_sched_context_create())) {
 		ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
-		return AST_MODULE_LOAD_FAILURE;
+		ao2_ref(iax2_tech.capabilities, -1);
+		iax2_tech.capabilities = NULL;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_sched_start_thread(sched)) {
 		ast_sched_context_destroy(sched);
+		ao2_ref(iax2_tech.capabilities, -1);
+		iax2_tech.capabilities = NULL;
 		sched = NULL;
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(io = io_context_create())) {
 		ast_log(LOG_ERROR, "Failed to create I/O context\n");
 		ast_sched_context_destroy(sched);
+		ao2_ref(iax2_tech.capabilities, -1);
+		iax2_tech.capabilities = NULL;
 		sched = NULL;
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(netsock = ast_netsock_list_alloc())) {
 		ast_log(LOG_ERROR, "Failed to create netsock list\n");
 		io_context_destroy(io);
 		ast_sched_context_destroy(sched);
+		ao2_ref(iax2_tech.capabilities, -1);
+		iax2_tech.capabilities = NULL;
 		sched = NULL;
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_netsock_init(netsock);
 
@@ -15137,8 +15147,10 @@ static int load_module(void)
 		ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
 		io_context_destroy(io);
 		ast_sched_context_destroy(sched);
+		ao2_ref(iax2_tech.capabilities, -1);
+		iax2_tech.capabilities = NULL;
 		sched = NULL;
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_netsock_init(outsock);
 
@@ -15157,6 +15169,7 @@ static int load_module(void)
 			ast_timer_close(timer);
 			timer = NULL;
 		}
+		__unload_module();
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
@@ -15182,7 +15195,7 @@ static int load_module(void)
  	if (ast_channel_register(&iax2_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
 		__unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_register_switch(&iax2_switch)) {
@@ -15192,7 +15205,7 @@ static int load_module(void)
 	if (start_network_thread()) {
 		ast_log(LOG_ERROR, "Unable to start network thread\n");
 		__unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	} else {
 		ast_verb(2, "IAX Ready and Listening\n");
 	}
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index af79e218e9c5bd8ef069586f5538775945c70183..6cac4bc8acb8c254c73d8e3d77abd41625c1a213 100644
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -4860,11 +4860,11 @@ static int reload_config(int reload)
 static int load_module(void)
 {
 	if (!(global_capability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	if (!(mgcp_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
 		ao2_ref(global_capability, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append(global_capability, ast_format_ulaw, 0);
 	ast_format_cap_append(mgcp_tech.capabilities, ast_format_ulaw, 0);
@@ -4873,7 +4873,7 @@ static int load_module(void)
 		ast_log(LOG_WARNING, "Unable to create schedule context\n");
 		ao2_ref(global_capability, -1);
 		ao2_ref(mgcp_tech.capabilities, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(io = io_context_create())) {
@@ -4881,7 +4881,7 @@ static int load_module(void)
 		ast_sched_context_destroy(sched);
 		ao2_ref(global_capability, -1);
 		ao2_ref(mgcp_tech.capabilities, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (reload_config(0)) {
@@ -4897,7 +4897,7 @@ static int load_module(void)
 		ast_sched_context_destroy(sched);
 		ao2_ref(global_capability, -1);
 		ao2_ref(mgcp_tech.capabilities, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	ast_rtp_glue_register(&mgcp_rtp_glue);
diff --git a/channels/chan_motif.c b/channels/chan_motif.c
index 5828a11559f31392fe616cb6094f0354bba5a381..7d696e87dc657996eb36e9302a4342a3a1e1638d 100644
--- a/channels/chan_motif.c
+++ b/channels/chan_motif.c
@@ -2788,7 +2788,7 @@ end:
 	ao2_cleanup(jingle_tech.capabilities);
 	jingle_tech.capabilities = NULL;
 
-	return AST_MODULE_LOAD_FAILURE;
+	return AST_MODULE_LOAD_DECLINE;
 }
 
 /*! \brief Reload module */
diff --git a/channels/chan_nbs.c b/channels/chan_nbs.c
index 61e5398c30eff93ca9c28258ccfddedc3350b0b5..a12470cee80e2351a7f08dfd3e91db3edc55d31b 100644
--- a/channels/chan_nbs.c
+++ b/channels/chan_nbs.c
@@ -257,12 +257,14 @@ static int unload_module(void)
 static int load_module(void)
 {
 	if (!(nbs_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append(nbs_tech.capabilities, ast_format_slin, 0);
 	/* Make sure we can register our channel type */
 	if (ast_channel_register(&nbs_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
+		ao2_ref(nbs_tech.capabilities, -1);
+		nbs_tech.capabilities = NULL;
 		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index 3e1e38d37a9c9a4ba0615744b798295030c3ba0e..ec112de38837969bcaa89669024840e881e09acc 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -1435,6 +1435,31 @@ error:
 #endif
 }
 
+static int unload_module(void)
+{
+	struct chan_oss_pvt *o, *next;
+
+	ast_channel_unregister(&oss_tech);
+	ast_cli_unregister_multiple(cli_oss, ARRAY_LEN(cli_oss));
+
+	o = oss_default.next;
+	while (o) {
+		close(o->sounddev);
+		if (o->owner)
+			ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
+		if (o->owner)
+			return -1;
+		next = o->next;
+		ast_free(o->name);
+		ast_free(o);
+		o = next;
+	}
+	ao2_cleanup(oss_tech.capabilities);
+	oss_tech.capabilities = NULL;
+
+	return 0;
+}
+
 /*!
  * \brief Load the module
  *
@@ -1472,12 +1497,12 @@ static int load_module(void)
 	if (find_desc(oss_active) == NULL) {
 		ast_log(LOG_NOTICE, "Device %s not found\n", oss_active);
 		/* XXX we could default to 'dsp' perhaps ? */
-		/* XXX should cleanup allocated memory etc. */
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(oss_tech.capabilities = ast_format_cap_alloc(0))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append(oss_tech.capabilities, ast_format_slin, 0);
 
@@ -1494,31 +1519,5 @@ static int load_module(void)
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
-
-static int unload_module(void)
-{
-	struct chan_oss_pvt *o, *next;
-
-	ast_channel_unregister(&oss_tech);
-	ast_cli_unregister_multiple(cli_oss, ARRAY_LEN(cli_oss));
-
-	o = oss_default.next;
-	while (o) {
-		close(o->sounddev);
-		if (o->owner)
-			ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
-		if (o->owner)
-			return -1;
-		next = o->next;
-		ast_free(o->name);
-		ast_free(o);
-		o = next;
-	}
-	ao2_cleanup(oss_tech.capabilities);
-	oss_tech.capabilities = NULL;
-
-	return 0;
-}
-
 AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "OSS Console Channel Driver");
 
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index aa10a56202d3656fdb95a9e8ef4a48101332a1cc..76891ac984c7cc8ff387b087c777e01ea0003d7d 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -1416,7 +1416,7 @@ static int load_module(void)
 	if (ast_mutex_lock(&iflock)) {
 		/* It's a little silly to lock it, but we mind as well just to be sure */
 		ast_log(LOG_ERROR, "Unable to lock interface list???\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	v = ast_variable_browse(cfg, "interfaces");
 	while(v) {
@@ -1432,7 +1432,7 @@ static int load_module(void)
 					ast_config_destroy(cfg);
 					ast_mutex_unlock(&iflock);
 					__unload_module();
-					return AST_MODULE_LOAD_FAILURE;
+					return AST_MODULE_LOAD_DECLINE;
 				}
 		} else if (!strcasecmp(v->name, "silencesupression")) {
 			silencesupression = ast_true(v->value);
@@ -1508,7 +1508,7 @@ static int load_module(void)
 		ast_log(LOG_ERROR, "Unable to register channel class 'Phone'\n");
 		ast_config_destroy(cfg);
 		__unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_config_destroy(cfg);
 	/* And start the monitor for the first time */
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index 46c74adf7913f70e48270b8cc59719addfc1c52f..a92816431bb9fa2b960c1cf7f63daf0e82a91c34 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -2749,7 +2749,7 @@ end:
 	ast_channel_unregister(&chan_pjsip_tech);
 	ast_rtp_glue_unregister(&chan_pjsip_rtp_glue);
 
-	return AST_MODULE_LOAD_FAILURE;
+	return AST_MODULE_LOAD_DECLINE;
 }
 
 /*! \brief Unload the PJSIP channel from Asterisk */
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 5419a1dd8b49f720d51fd819430a5991619c6a14..affe937e803540aad2651c2ec9eeee2bc33622b0 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -35287,17 +35287,17 @@ static int load_module(void)
 
 	if (STASIS_MESSAGE_TYPE_INIT(session_timeout_type)) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(sip_tech.capabilities = ast_format_cap_alloc(0))) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_sip_api_provider_register(&chan_sip_api_provider)) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* the fact that ao2_containers can't resize automatically is a major worry! */
@@ -35312,12 +35312,12 @@ static int load_module(void)
 		|| !threadt) {
 		ast_log(LOG_ERROR, "Unable to create primary SIP container(s)\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(sip_cfg.caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append_by_type(sip_tech.capabilities, AST_MEDIA_TYPE_AUDIO);
 
@@ -35328,13 +35328,13 @@ static int load_module(void)
 	if (!(sched = ast_sched_context_create())) {
 		ast_log(LOG_ERROR, "Unable to create scheduler context\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(io = io_context_create())) {
 		ast_log(LOG_ERROR, "Unable to create I/O context\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	sip_reloadreason = CHANNEL_MODULE_LOAD;
@@ -35349,7 +35349,7 @@ static int load_module(void)
 	if (!(bogus_peer = temp_peer("(bogus_peer)"))) {
 		ast_log(LOG_ERROR, "Unable to create bogus_peer for authentication\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	/* Make sure the auth will always fail. */
 	ast_string_field_set(bogus_peer, md5secret, BOGUS_PEER_MD5SECRET);
@@ -35366,14 +35366,14 @@ static int load_module(void)
 
 	if (ast_msg_tech_register(&sip_msg_tech)) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Make sure we can register our sip channel type */
 	if (ast_channel_register(&sip_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 #ifdef TEST_FRAMEWORK
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index d1c2b927a61385f7733657c0363adf8fb9a9c673..a0530007b18b7b16f94f68a753d4f9f92b0aeb6d 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -8698,7 +8698,7 @@ static int load_module(void)
 		ao2_ref(skinny_tech.capabilities, -1);
 		ao2_ref(default_cap, -1);
 		ast_log(LOG_WARNING, "Unable to create schedule context\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Make sure we can register our skinny channel type */
@@ -8706,7 +8706,7 @@ static int load_module(void)
 		ao2_ref(default_cap, -1);
 		ao2_ref(skinny_tech.capabilities, -1);
 		ast_log(LOG_ERROR, "Unable to register channel class 'Skinny'\n");
-		return -1;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	ast_rtp_glue_register(&skinny_rtp_glue);
@@ -8723,7 +8723,7 @@ static int load_module(void)
 		ast_channel_unregister(&skinny_tech);
 		ao2_ref(default_cap, -1);
 		ao2_ref(skinny_tech.capabilities, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c
index f82522111e2564dc95dda90ac1707fb89ec88c49..b820cf51e9b4a29d895f845e2c3e0b2385bbaaa2 100644
--- a/channels/chan_unistim.c
+++ b/channels/chan_unistim.c
@@ -7126,7 +7126,7 @@ buff_failed:
 	global_cap = NULL;
 	ao2_cleanup(unistim_tech.capabilities);
 	unistim_tech.capabilities = NULL;
-	return AST_MODULE_LOAD_FAILURE;
+	return AST_MODULE_LOAD_DECLINE;
 }
 
 static int unload_module(void)
diff --git a/codecs/codec_a_mu.c b/codecs/codec_a_mu.c
index ea8d01488c4c5d4957f9c80cfe6b0a90e5aa7378..a2cce4ef78e05f496c7f01c8683a73892fa61f86 100644
--- a/codecs/codec_a_mu.c
+++ b/codecs/codec_a_mu.c
@@ -141,7 +141,7 @@ static int load_module(void)
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_adpcm.c b/codecs/codec_adpcm.c
index 3076d264e2b9984568cd2e93bbc2bfa145764c67..0b2f90f3985171095a1530db684cbd56012487f2 100644
--- a/codecs/codec_adpcm.c
+++ b/codecs/codec_adpcm.c
@@ -346,7 +346,7 @@ static int load_module(void)
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_alaw.c b/codecs/codec_alaw.c
index ba16936b551535d566ff62358cda536fdea61f44..ebaca74c551f3dce366cff319bdade1640f50ccc 100644
--- a/codecs/codec_alaw.c
+++ b/codecs/codec_alaw.c
@@ -130,7 +130,7 @@ static int load_module(void)
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_g722.c b/codecs/codec_g722.c
index 9c868d3d9ba0af130dc14cb3d88b5cca018bfec7..48b5e4a27aa2cbd9419d5b453f7ffc65e93ba32d 100644
--- a/codecs/codec_g722.c
+++ b/codecs/codec_g722.c
@@ -241,7 +241,7 @@ static int load_module(void)
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}	
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_g726.c b/codecs/codec_g726.c
index 4bf39b7cec00b3ffd80a9789b4f50d093537acf9..3b76628d52713120a089802332a35cb2b96c572d 100644
--- a/codecs/codec_g726.c
+++ b/codecs/codec_g726.c
@@ -890,7 +890,7 @@ static int load_module(void)
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}	
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_gsm.c b/codecs/codec_gsm.c
index 2ae42a6c0c572ff07c22b04e87075582712ade27..296747ee3cb28ac5b4a67775ae720752ffbbb84f 100644
--- a/codecs/codec_gsm.c
+++ b/codecs/codec_gsm.c
@@ -239,7 +239,7 @@ static int load_module(void)
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_ilbc.c b/codecs/codec_ilbc.c
index 16466a9c9d4d8ee17a099922803d1a3ecdd9d754..d691f706f3e052dfc4e5f9efa370906ffb84c517 100644
--- a/codecs/codec_ilbc.c
+++ b/codecs/codec_ilbc.c
@@ -267,7 +267,7 @@ static int load_module(void)
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_lpc10.c b/codecs/codec_lpc10.c
index 5f6ffff8716b3ba22ae788882747dd78a58ace36..00e30226748f7ef7b1af23958db20bd4b17e8684 100644
--- a/codecs/codec_lpc10.c
+++ b/codecs/codec_lpc10.c
@@ -272,7 +272,7 @@ static int load_module(void)
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_resample.c b/codecs/codec_resample.c
index b54f5c9219784d757788b3c407acdaf5b24dfb32..e0d530d85709fb7dd406a13d3791e27108d56338 100644
--- a/codecs/codec_resample.c
+++ b/codecs/codec_resample.c
@@ -153,7 +153,7 @@ static int load_module(void)
 
 	trans_size = ARRAY_LEN(codec_list) * (ARRAY_LEN(codec_list) - 1);
 	if (!(translators = ast_calloc(1, sizeof(struct ast_translator) * trans_size))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	for (x = 0; x < ARRAY_LEN(codec_list); x++) {
@@ -180,7 +180,7 @@ static int load_module(void)
 	ast_unregister_translator won't fail.*/
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_ulaw.c b/codecs/codec_ulaw.c
index cf4e358da97349953b87e3e09c29a0ed8e3e5b31..e0a4f6841fd3a8c4e866306d72a3782f8e6f334a 100644
--- a/codecs/codec_ulaw.c
+++ b/codecs/codec_ulaw.c
@@ -181,7 +181,7 @@ static int load_module(void)
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/formats/format_g723.c b/formats/format_g723.c
index 750bacaf153853bec865ea0721449b487711a76e..04e03b6086f12a34d9d526f6d967011c4bfa538d 100644
--- a/formats/format_g723.c
+++ b/formats/format_g723.c
@@ -142,7 +142,7 @@ static int load_module(void)
 	g723_1_f.format = ast_format_g723;
 
 	if (ast_format_def_register(&g723_1_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_g726.c b/formats/format_g726.c
index f3b09f0351e36046b22ae2256ea02b57c5fd9624..08e669e264fe62fb830014642b2777567e305854 100644
--- a/formats/format_g726.c
+++ b/formats/format_g726.c
@@ -221,29 +221,30 @@ static struct ast_format_def f[] = {
 	{	.desc_size = 0 }	/* terminator */
 };
 
-static int load_module(void)
+static int unload_module(void)
 {
 	int i;
 
 	for (i = 0; f[i].desc_size ; i++) {
-		f[i].format = ast_format_g726;
-		if (ast_format_def_register(&f[i])) {	/* errors are fatal */
-			ast_log(LOG_WARNING, "Failed to register format %s.\n", f[i].name);
-			return AST_MODULE_LOAD_FAILURE;
-		}
+		if (ast_format_def_unregister(f[i].name))
+			ast_log(LOG_WARNING, "Failed to unregister format %s.\n", f[i].name);
 	}
-	return AST_MODULE_LOAD_SUCCESS;
+	return(0);
 }
 
-static int unload_module(void)
+static int load_module(void)
 {
 	int i;
 
 	for (i = 0; f[i].desc_size ; i++) {
-		if (ast_format_def_unregister(f[i].name))
-			ast_log(LOG_WARNING, "Failed to unregister format %s.\n", f[i].name);
+		f[i].format = ast_format_g726;
+		if (ast_format_def_register(&f[i])) {	/* errors are fatal */
+			ast_log(LOG_WARNING, "Failed to register format %s.\n", f[i].name);
+			unload_module();
+			return AST_MODULE_LOAD_DECLINE;
+		}
 	}
-	return(0);
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw G.726 (16/24/32/40kbps) data",
diff --git a/formats/format_g729.c b/formats/format_g729.c
index 6e0632c5351dc83675343e10c1a9173a8477cd89..49e58025f88db18752c1be1f26289f247b82ba55 100644
--- a/formats/format_g729.c
+++ b/formats/format_g729.c
@@ -138,7 +138,7 @@ static int load_module(void)
 {
 	g729_f.format = ast_format_g729;
 	if (ast_format_def_register(&g729_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_gsm.c b/formats/format_gsm.c
index 777d49a636ff2c5840e3aaf8183b22f16acaebb3..a2b6d365616352a3861e833d7b5d351402c1b44a 100644
--- a/formats/format_gsm.c
+++ b/formats/format_gsm.c
@@ -183,7 +183,7 @@ static int load_module(void)
 {
 	gsm_f.format = ast_format_gsm;
 	if (ast_format_def_register(&gsm_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_h263.c b/formats/format_h263.c
index 027f604f4accfe4aced46668b1bf3143a88d3139..4cc3db54272bb6652582dd5131dc5eae4bb6abd3 100644
--- a/formats/format_h263.c
+++ b/formats/format_h263.c
@@ -170,7 +170,7 @@ static int load_module(void)
 {
 	h263_f.format = ast_format_h263;
 	if (ast_format_def_register(&h263_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_h264.c b/formats/format_h264.c
index 38f2734f3c1f0f217d01d255de45c06dafc932d7..60b0902111cb3f7437a51e0e64648a2e226a9403 100644
--- a/formats/format_h264.c
+++ b/formats/format_h264.c
@@ -163,7 +163,7 @@ static int load_module(void)
 {
 	h264_f.format = ast_format_h264;
 	if (ast_format_def_register(&h264_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_ilbc.c b/formats/format_ilbc.c
index b556d6cc854c7c267bdf090425674fce510840d7..eab465d8871f629a8c246a04aa1623b969a85951 100644
--- a/formats/format_ilbc.c
+++ b/formats/format_ilbc.c
@@ -135,7 +135,7 @@ static int load_module(void)
 {
 	ilbc_f.format = ast_format_ilbc;
 	if (ast_format_def_register(&ilbc_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_jpeg.c b/formats/format_jpeg.c
index f69c547d360ac33ba050bf1014d3b8006b71f7f2..798141d555ec023850fc5fe83be9ee2a44112285 100644
--- a/formats/format_jpeg.c
+++ b/formats/format_jpeg.c
@@ -96,7 +96,7 @@ static int load_module(void)
 {
 	jpeg_format.format = ast_format_jpeg;
 	if (ast_image_register(&jpeg_format))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_ogg_vorbis.c b/formats/format_ogg_vorbis.c
index 4c42181fcfb99b3baec685364e28f94ff7881c61..d4212a169b43db4afa2263e5b868d5ea82b2e4f8 100644
--- a/formats/format_ogg_vorbis.c
+++ b/formats/format_ogg_vorbis.c
@@ -423,7 +423,7 @@ static int load_module(void)
 {
 	vorbis_f.format = ast_format_slin;
 	if (ast_format_def_register(&vorbis_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_pcm.c b/formats/format_pcm.c
index 0b1706e504ac9948c37a37157fecbf1ef19398e3..fedc0632f2bece65601bcfdfae147c2644bb057f 100644
--- a/formats/format_pcm.c
+++ b/formats/format_pcm.c
@@ -500,6 +500,14 @@ static struct ast_format_def au_f = {
 	.buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,	/* this many shorts */
 };
 
+static int unload_module(void)
+{
+	return ast_format_def_unregister(pcm_f.name)
+		|| ast_format_def_unregister(alaw_f.name)
+		|| ast_format_def_unregister(au_f.name)
+		|| ast_format_def_unregister(g722_f.name);
+}
+
 static int load_module(void)
 {
 	int i;
@@ -517,19 +525,13 @@ static int load_module(void)
 	if ( ast_format_def_register(&pcm_f)
 		|| ast_format_def_register(&alaw_f)
 		|| ast_format_def_register(&au_f)
-		|| ast_format_def_register(&g722_f) )
-		return AST_MODULE_LOAD_FAILURE;
+		|| ast_format_def_register(&g722_f) ) {
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
+	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
-static int unload_module(void)
-{
-	return ast_format_def_unregister(pcm_f.name)
-		|| ast_format_def_unregister(alaw_f.name)
-		|| ast_format_def_unregister(au_f.name)
-		|| ast_format_def_unregister(g722_f.name);
-}
-
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw/Sun uLaw/ALaw 8KHz (PCM,PCMA,AU), G.722 16Khz",
 	.support_level = AST_MODULE_SUPPORT_CORE,
 	.load = load_module,
diff --git a/formats/format_sln.c b/formats/format_sln.c
index 32972d09d07f3d4d77b553c287a2531fa75d2022..af3f691c81c253f7e0f4ce7028f87c1dfb1f8669 100644
--- a/formats/format_sln.c
+++ b/formats/format_sln.c
@@ -235,6 +235,19 @@ static struct ast_format_def *slin_list[] = {
 	&slin192_f,
 };
 
+static int unload_module(void)
+{
+	int res = 0;
+	int i = 0;
+
+	for (i = 0; i < ARRAY_LEN(slin_list); i++) {
+		if (ast_format_def_unregister(slin_list[i]->name)) {
+			res = -1;
+		}
+	}
+	return res;
+}
+
 static int load_module(void)
 {
 	int i;
@@ -251,26 +264,14 @@ static int load_module(void)
 
 	for (i = 0; i < ARRAY_LEN(slin_list); i++) {
 		if (ast_format_def_register(slin_list[i])) {
-			return AST_MODULE_LOAD_FAILURE;
+			unload_module();
+			return AST_MODULE_LOAD_DECLINE;
 		}
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
-static int unload_module(void)
-{
-	int res = 0;
-	int i = 0;
-
-	for (i = 0; i < ARRAY_LEN(slin_list); i++) {
-		if (ast_format_def_unregister(slin_list[i]->name)) {
-			res |= AST_MODULE_LOAD_FAILURE;
-		}
-	}
-	return res;
-}
-
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw Signed Linear Audio support (SLN) 8khz-192khz",
 	.support_level = AST_MODULE_SUPPORT_CORE,
 	.load = load_module,
diff --git a/formats/format_vox.c b/formats/format_vox.c
index eb8ab0eadb1bdf11693e8f32043ffd2406ede1dc..5a70c34b140a7c4ab1f39236f007b6fac9043621 100644
--- a/formats/format_vox.c
+++ b/formats/format_vox.c
@@ -137,7 +137,7 @@ static int load_module(void)
 {
 	vox_f.format = ast_format_adpcm;
 	if (ast_format_def_register(&vox_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_wav.c b/formats/format_wav.c
index a415140f9f3efb85ba2c9b55fe3f675869056ef4..049ead40ee0bef9ac74fd11c0c2af9346e75ca40 100644
--- a/formats/format_wav.c
+++ b/formats/format_wav.c
@@ -536,22 +536,24 @@ static struct ast_format_def wav_f = {
 	.desc_size = sizeof(struct wav_desc),
 };
 
+static int unload_module(void)
+{
+	return ast_format_def_unregister(wav_f.name)
+		|| ast_format_def_unregister(wav16_f.name);
+}
+
 static int load_module(void)
 {
 	wav_f.format = ast_format_slin;
 	wav16_f.format = ast_format_slin16;
 	if (ast_format_def_register(&wav_f)
-		|| ast_format_def_register(&wav16_f))
-		return AST_MODULE_LOAD_FAILURE;
+		|| ast_format_def_register(&wav16_f)) {
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
+	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
-static int unload_module(void)
-{
-	return ast_format_def_unregister(wav_f.name)
-		|| ast_format_def_unregister(wav16_f.name);
-}
-
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Microsoft WAV/WAV16 format (8kHz/16kHz Signed Linear)",
 	.support_level = AST_MODULE_SUPPORT_CORE,
 	.load = load_module,
diff --git a/formats/format_wav_gsm.c b/formats/format_wav_gsm.c
index 21a8508059f2278990bd85b3e52d7033cd7ba79f..eef06cef5b72d5c3bee62866c62f58aff131aa31 100644
--- a/formats/format_wav_gsm.c
+++ b/formats/format_wav_gsm.c
@@ -568,7 +568,7 @@ static int load_module(void)
 {
 	wav49_f.format = ast_format_gsm;
 	if (ast_format_def_register(&wav49_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/funcs/func_cdr.c b/funcs/func_cdr.c
index 83942db4cd261c4a1c8d82121a878cbb960752fc..82ff488b047846e2eb38c0fd1bf3cc5992e6a711 100644
--- a/funcs/func_cdr.c
+++ b/funcs/func_cdr.c
@@ -649,7 +649,7 @@ static int load_module(void)
 	int res = 0;
 
 	if (!router) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	res |= STASIS_MESSAGE_TYPE_INIT(cdr_read_message_type);
@@ -665,7 +665,8 @@ static int load_module(void)
 	                                 cdr_read_callback, NULL);
 
 	if (res) {
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
diff --git a/funcs/func_holdintercept.c b/funcs/func_holdintercept.c
index c2435463a0def6b9c5a4a0e990a47192892c9a44..2a1cbb8c148c4da47ad5e609178c93e7e1fc70a9 100644
--- a/funcs/func_holdintercept.c
+++ b/funcs/func_holdintercept.c
@@ -228,7 +228,7 @@ static int unload_module(void)
 /*! \internal \brief Load the module */
 static int load_module(void)
 {
-	return ast_custom_function_register(&hold_intercept_function) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS;
+	return ast_custom_function_register(&hold_intercept_function) ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Hold interception dialplan function");
diff --git a/funcs/func_talkdetect.c b/funcs/func_talkdetect.c
index 02963f20e4ffd4ae803e08be86b73ff1d3109131..5c7f41ab398e629dcfe2e145ca2f44fcc556e181 100644
--- a/funcs/func_talkdetect.c
+++ b/funcs/func_talkdetect.c
@@ -397,7 +397,7 @@ static int load_module(void)
 
 	res |= ast_custom_function_register(&talk_detect_function);
 
-	return res ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS;
+	return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Talk detection dialplan function");
diff --git a/include/asterisk/logger.h b/include/asterisk/logger.h
index 9f9f671c06f00586a01f6a4a6c1b39c3c17ce51e..2f629dfbef582d0ead1a010edffb0fdb35bcd67b 100644
--- a/include/asterisk/logger.h
+++ b/include/asterisk/logger.h
@@ -500,6 +500,13 @@ int ast_verb_console_get(void);
  */
 void ast_verb_console_set(int verb_level);
 
+/*!
+ * \brief Test if logger is initialized
+ *
+ * \retval true if the logger is initialized
+ */
+int ast_is_logger_initialized(void);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif
diff --git a/main/asterisk.c b/main/asterisk.c
index 68859ab2fad40edcf248396a24779985648d1612..16313ea685312f017cba277d09f89c835e45bde3 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -4354,7 +4354,11 @@ int main(int argc, char *argv[])
 static inline void check_init(int init_result, const char *name)
 {
 	if (init_result) {
-		printf("%s initialization failed.\n%s", name, term_quit());
+		if (ast_is_logger_initialized()) {
+			ast_log(LOG_ERROR, "%s initialization failed.  ASTERISK EXITING!\n%s", name, term_quit());
+		} else {
+			fprintf(stderr, "%s initialization failed.  ASTERISK EXITING!\n%s", name, term_quit());
+		}
 		ast_run_atexits(0);
 		exit(init_result == -2 ? 2 : 1);
 	}
diff --git a/main/loader.c b/main/loader.c
index 380fe1c92fab5c09c331daae27f712ddb290693e..d5500076b4e66f0e7f040fdb13b0bb7d6da07a29 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -1243,6 +1243,7 @@ static int load_resource_list(struct load_order *load_order, unsigned int global
 		case AST_MODULE_LOAD_DECLINE:
 			break;
 		case AST_MODULE_LOAD_FAILURE:
+			ast_log(LOG_ERROR, "*** Failed to load module %s\n", mod->resource);
 			res = -1;
 			goto done;
 		case AST_MODULE_LOAD_SKIP:
diff --git a/main/logger.c b/main/logger.c
index 146d91985556872add2baadc620ca1c5bb6fab4a..8c8162d718defb144e43420ff7067a1a100b5aaa 100644
--- a/main/logger.c
+++ b/main/logger.c
@@ -1653,6 +1653,11 @@ static void logger_queue_init(void)
 	}
 }
 
+int ast_is_logger_initialized(void)
+{
+	return logger_initialized;
+}
+
 /*!
  * \brief Start the ast_queue_log() logger.
  *
diff --git a/res/res_ari.c b/res/res_ari.c
index 549d7835365fce167c0375717775df6ab98f7bc1..054d3bf3c59c35374307c56aca313668d1d98221 100644
--- a/res/res_ari.c
+++ b/res/res_ari.c
@@ -1106,6 +1106,27 @@ static struct ast_http_uri http_uri = {
 	.no_decode_uri = 1,
 };
 
+static int unload_module(void)
+{
+	ast_ari_cli_unregister();
+
+	if (is_enabled()) {
+		ast_debug(3, "Disabling ARI\n");
+		ast_http_uri_unlink(&http_uri);
+	}
+
+	ast_ari_config_destroy();
+
+	ao2_cleanup(root_handler);
+	root_handler = NULL;
+	ast_mutex_destroy(&root_handler_lock);
+
+	ast_json_unref(oom_json);
+	oom_json = NULL;
+
+	return 0;
+}
+
 static int load_module(void)
 {
 	ast_mutex_init(&root_handler_lock);
@@ -1115,7 +1136,7 @@ static int load_module(void)
 		root_handler = root_handler_create();
 	}
 	if (!root_handler) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* oom_json may have been built during a declined load */
@@ -1125,10 +1146,12 @@ static int load_module(void)
 	}
 	if (!oom_json) {
 		/* Ironic */
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_ari_config_init() != 0) {
+		unload_module();
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
@@ -1140,33 +1163,13 @@ static int load_module(void)
 	}
 
 	if (ast_ari_cli_register() != 0) {
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
-static int unload_module(void)
-{
-	ast_ari_cli_unregister();
-
-	if (is_enabled()) {
-		ast_debug(3, "Disabling ARI\n");
-		ast_http_uri_unlink(&http_uri);
-	}
-
-	ast_ari_config_destroy();
-
-	ao2_cleanup(root_handler);
-	root_handler = NULL;
-	ast_mutex_destroy(&root_handler_lock);
-
-	ast_json_unref(oom_json);
-	oom_json = NULL;
-
-	return 0;
-}
-
 static int reload_module(void)
 {
 	char was_enabled = is_enabled();
diff --git a/res/res_ari_events.c b/res/res_ari_events.c
index 8ccb8870c8c9254dc0e6919b7131b658f587afa3..8d8a303d1a8c4ba9dd588309cc6329755363cf3e 100644
--- a/res/res_ari_events.c
+++ b/res/res_ari_events.c
@@ -417,6 +417,15 @@ static struct stasis_rest_handlers events = {
 	.children = { &events_user, }
 };
 
+static int unload_module(void)
+{
+	ast_ari_remove_handler(&events);
+	ao2_cleanup(events.ws_server);
+	events.ws_server = NULL;
+	stasis_app_unref();
+	return 0;
+}
+
 static int load_module(void)
 {
 	int res = 0;
@@ -428,31 +437,27 @@ static int load_module(void)
 
 	events.ws_server = ast_websocket_server_create();
 	if (!events.ws_server) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	protocol = ast_websocket_sub_protocol_alloc("ari");
 	if (!protocol) {
 		ao2_ref(events.ws_server, -1);
 		events.ws_server = NULL;
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	protocol->session_attempted = ast_ari_events_event_websocket_ws_attempted_cb;
 	protocol->session_established = ast_ari_events_event_websocket_ws_established_cb;
 	res |= ast_websocket_server_add_protocol2(events.ws_server, protocol);
 	stasis_app_ref();
 	res |= ast_ari_add_handler(&events);
-	return res;
-}
 
-static int unload_module(void)
-{
-	ast_ari_remove_handler(&events);
-	ao2_cleanup(events.ws_server);
-	events.ws_server = NULL;
-	ast_ari_websocket_events_event_websocket_dtor();
-	stasis_app_unref();
-	return 0;
+	if (res) {
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - WebSocket resource",
diff --git a/res/res_ari_model.c b/res/res_ari_model.c
index dd8e1af388abca4bfbf3935931c50a4ced787bc8..015b1e73f1d8eb398910773962b5070a09b4c837 100644
--- a/res/res_ari_model.c
+++ b/res/res_ari_model.c
@@ -190,7 +190,7 @@ static int load_module(void)
 		REG_EXTENDED | REG_ICASE | REG_NOSUB);
 
 	if (res != 0) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
diff --git a/res/res_calendar.c b/res/res_calendar.c
index 92b73c1edc8e7ca9b462b158967bef712b5945aa..666b0e18407eeec33344e3f139a6a932842fccfd 100644
--- a/res/res_calendar.c
+++ b/res/res_calendar.c
@@ -1888,7 +1888,7 @@ static int load_module(void)
 {
 	if (!(calendars = ao2_container_alloc(CALENDAR_BUCKETS, calendar_hash_fn, calendar_cmp_fn))) {
 		ast_log(LOG_ERROR, "Unable to allocate calendars container!\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (load_config(0)) {
@@ -1902,7 +1902,9 @@ static int load_module(void)
 
 	if (!(sched = ast_sched_context_create())) {
 		ast_log(LOG_ERROR, "Unable to create sched context\n");
-		return AST_MODULE_LOAD_FAILURE;
+		ast_config_destroy(calendar_config);
+		calendar_config = NULL;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_pthread_create_background(&refresh_thread, NULL, do_refresh, NULL) < 0) {
diff --git a/res/res_chan_stats.c b/res/res_chan_stats.c
index 9a26db78c2c57e27b7a19647bc0d3161555139bf..061d0867eb3f85eba49766acac49fe27ee682228 100644
--- a/res/res_chan_stats.c
+++ b/res/res_chan_stats.c
@@ -148,13 +148,22 @@ static void default_route(void *data, struct stasis_subscription *sub,
 	}
 }
 
+static int unload_module(void)
+{
+	stasis_unsubscribe_and_join(sub);
+	sub = NULL;
+	stasis_message_router_unsubscribe_and_join(router);
+	router = NULL;
+	return 0;
+}
+
 static int load_module(void)
 {
 	/* You can create a message router to route messages by type */
 	router = stasis_message_router_create(
 		ast_channel_topic_all_cached());
 	if (!router) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	stasis_message_router_add(router, stasis_cache_update_type(),
 		updates, NULL);
@@ -163,20 +172,12 @@ static int load_module(void)
 	/* Or a subscription to receive all of the messages from a topic */
 	sub = stasis_subscribe(ast_channel_topic_all(), statsmaker, NULL);
 	if (!sub) {
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
-static int unload_module(void)
-{
-	stasis_unsubscribe_and_join(sub);
-	sub = NULL;
-	stasis_message_router_unsubscribe_and_join(router);
-	router = NULL;
-	return 0;
-}
-
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Example of how to use Stasis",
 	.support_level = AST_MODULE_SUPPORT_EXTENDED,
 	.load = load_module,
diff --git a/res/res_config_sqlite.c b/res/res_config_sqlite.c
index 96a10b43f952cc554e9c7ecdb9cfa60c41b07384..0f9113188b7c0d0f876e54eefc9781f35368bdbf 100644
--- a/res/res_config_sqlite.c
+++ b/res/res_config_sqlite.c
@@ -1680,7 +1680,7 @@ static int load_module(void)
 		ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
 		sqlite_freemem(errormsg);
 		unload_module();
-		return 1;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	sqlite_freemem(errormsg);
@@ -1700,7 +1700,7 @@ static int load_module(void)
 		if (!query) {
 			ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
 			unload_module();
-			return 1;
+			return AST_MODULE_LOAD_DECLINE;
 		}
 
 		ast_debug(1, "SQL query: %s\n", query);
@@ -1719,7 +1719,7 @@ static int load_module(void)
 				ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
 				sqlite_freemem(errormsg);
 				unload_module();
-				return 1;
+				return AST_MODULE_LOAD_DECLINE;
 			}
 
 			sqlite_freemem(errormsg);
@@ -1729,7 +1729,7 @@ static int load_module(void)
 			if (!query) {
 				ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
 				unload_module();
-				return 1;
+				return AST_MODULE_LOAD_DECLINE;
 			}
 
 			ast_debug(1, "SQL query: %s\n", query);
@@ -1744,7 +1744,7 @@ static int load_module(void)
 				ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
 				sqlite_freemem(errormsg);
 				unload_module();
-				return 1;
+				return AST_MODULE_LOAD_DECLINE;
 			}
 		}
 		sqlite_freemem(errormsg);
@@ -1754,7 +1754,7 @@ static int load_module(void)
 
 		if (error) {
 			unload_module();
-			return 1;
+			return AST_MODULE_LOAD_DECLINE;
 		}
 
 		cdr_registered = 1;
@@ -1764,12 +1764,12 @@ static int load_module(void)
 
 	if (error) {
 		unload_module();
-		return 1;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	cli_status_registered = 1;
 
-	return 0;
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Realtime SQLite configuration",
diff --git a/res/res_config_sqlite3.c b/res/res_config_sqlite3.c
index 087843a68057efe297584416859b1e7827ab6fed..0025548be3b055fb6ae30e26535b6f3887967a18 100644
--- a/res/res_config_sqlite3.c
+++ b/res/res_config_sqlite3.c
@@ -1359,18 +1359,18 @@ static int load_module(void)
 	discover_sqlite3_caps();
 
 	if (!((databases = ao2_container_alloc(DB_BUCKETS, db_hash_fn, db_cmp_fn)))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (parse_config(0)) {
 		ao2_ref(databases, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(ast_config_engine_register(&sqlite3_config_engine))) {
 		ast_log(LOG_ERROR, "The config API must have changed, this shouldn't happen.\n");
 		ao2_ref(databases, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/res/res_endpoint_stats.c b/res/res_endpoint_stats.c
index 249cbea9bb8c3326bd1c466b132a13cdcbdadd3f..1e3f104c2120c28b611d0edb046ff36c978713f3 100644
--- a/res/res_endpoint_stats.c
+++ b/res/res_endpoint_stats.c
@@ -118,7 +118,7 @@ static int load_module(void)
 
 	router = stasis_message_router_create(ast_endpoint_topic_all_cached());
 	if (!router) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	stasis_message_router_add(router, stasis_cache_update_type(), cache_update_cb, NULL);
 
diff --git a/res/res_hep_rtcp.c b/res/res_hep_rtcp.c
index 25b90c7a266259d8957234e7c422f4b060eb5dee..7191f466163040226e4ad7660726f543088b2fa8 100644
--- a/res/res_hep_rtcp.c
+++ b/res/res_hep_rtcp.c
@@ -155,7 +155,7 @@ static int load_module(void)
 	stasis_rtp_subscription = stasis_subscribe(ast_rtp_topic(),
 		rtp_topic_handler, NULL);
 	if (!stasis_rtp_subscription) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c
index 799eb848fad35308ae2b538555a5e609f1d79d0b..60332f591dc63f8077c2d40706d41cac549bb361 100644
--- a/res/res_http_websocket.c
+++ b/res/res_http_websocket.c
@@ -1441,7 +1441,7 @@ static int load_module(void)
 {
 	websocketuri.data = websocket_server_internal_create();
 	if (!websocketuri.data) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_http_uri_link(&websocketuri);
 	websocket_add_protocol_internal("echo", websocket_echo_callback);
diff --git a/res/res_limit.c b/res/res_limit.c
index bff777d99095cd158deda5f690b5bd2deb72ec58..a308c41218f3600b21bd46ac479e7253240f2fc4 100644
--- a/res/res_limit.c
+++ b/res/res_limit.c
@@ -209,7 +209,7 @@ static int unload_module(void)
 
 static int load_module(void)
 {
-	return ast_cli_register(&cli_ulimit) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS;
+	return ast_cli_register(&cli_ulimit) ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Resource limits");
diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c
index d180296f420a91cfef07ef19da3a696a686d5a78..62bc9d67db258f7c36b5c47d021c4276ab838c22 100644
--- a/res/res_pjsip/config_transport.c
+++ b/res/res_pjsip/config_transport.c
@@ -1348,7 +1348,7 @@ int ast_sip_initialize_sorcery_transport(void)
 	transport_states = ao2_container_alloc(DEFAULT_STATE_BUCKETS, internal_state_hash, internal_state_cmp);
 	if (!transport_states) {
 		ast_log(LOG_ERROR, "Unable to allocate transport states container\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return -1;
 	}
 
 	ast_sorcery_apply_default(sorcery, "transport", "config", "pjsip.conf,criteria=type=transport");
diff --git a/res/res_pjsip_nat.c b/res/res_pjsip_nat.c
index a26180bc0b8ed6f825f5373d33300b5db2497ce2..9205622d7ad4fc09afe337021bb635314e96f72a 100644
--- a/res/res_pjsip_nat.c
+++ b/res/res_pjsip_nat.c
@@ -361,13 +361,13 @@ static int load_module(void)
 
 	if (ast_sip_register_service(&nat_module)) {
 		ast_log(LOG_ERROR, "Could not register NAT module for incoming and outgoing requests\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_sip_session_register_supplement(&nat_supplement)) {
 		ast_log(LOG_ERROR, "Could not register NAT session supplement for incoming and outgoing INVITE requests\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/res/res_pjsip_one_touch_record_info.c b/res/res_pjsip_one_touch_record_info.c
index 2d53fd48ee0760cd4844c40cd715f283820c8e80..ec5f9be3e7cdacce04ff1583bbc100a2ab4f0234 100644
--- a/res/res_pjsip_one_touch_record_info.c
+++ b/res/res_pjsip_one_touch_record_info.c
@@ -112,7 +112,7 @@ static int load_module(void)
 
 	if (ast_sip_session_register_supplement(&info_supplement)) {
 		ast_log(LOG_ERROR, "Unable to register One Touch Recording supplement\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/res/res_pjsip_outbound_publish.c b/res/res_pjsip_outbound_publish.c
index a19a9bb2441757cc9b6855ec2a376086a8215082..c413cb0e13c1de5240806d4539f25e26cf015776 100644
--- a/res/res_pjsip_outbound_publish.c
+++ b/res/res_pjsip_outbound_publish.c
@@ -1631,7 +1631,7 @@ static int load_module(void)
 
 	shutdown_group = ast_serializer_shutdown_group_alloc();
 	if (!shutdown_group) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_outbound_publish");
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index 704239bd01ae1e1bde00538b46a1c810bf30b624..8a840ff05ebb014824fcf92bc68b6f100316038d 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -2082,7 +2082,7 @@ static int load_module(void)
 
 	shutdown_group = ast_serializer_shutdown_group_alloc();
 	if (!shutdown_group) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Create outbound registration states container. */
@@ -2091,7 +2091,7 @@ static int load_module(void)
 	if (!new_states) {
 		ast_log(LOG_ERROR, "Unable to allocate registration states container\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ao2_global_obj_replace_unref(current_states, new_states);
 	ao2_ref(new_states, -1);
@@ -2135,7 +2135,7 @@ static int load_module(void)
 			&registration_observer)) {
 		ast_log(LOG_ERROR, "Unable to register observers.\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Register how this module identifies endpoints. */
@@ -2146,7 +2146,7 @@ static int load_module(void)
 	if (!cli_formatter) {
 		ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	cli_formatter->name = "registration";
 	cli_formatter->print_header = cli_print_header;
diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c
index f0467627ea5820fc6f6728bb7576f211dda5c6b8..a1f3f246257e4cde0a08d6e40031fdfcb9d9077e 100644
--- a/res/res_pjsip_pubsub.c
+++ b/res/res_pjsip_pubsub.c
@@ -5225,13 +5225,13 @@ static int load_module(void)
 
 	if (!(sched = ast_sched_context_create())) {
 		ast_log(LOG_ERROR, "Could not create scheduler for publication expiration\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_sched_start_thread(sched)) {
 		ast_log(LOG_ERROR, "Could not start scheduler thread for publication expiration\n");
 		ast_sched_context_destroy(sched);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &str_PUBLISH);
@@ -5239,7 +5239,7 @@ static int load_module(void)
 	if (ast_sip_register_service(&pubsub_module)) {
 		ast_log(LOG_ERROR, "Could not register pubsub service\n");
 		ast_sched_context_destroy(sched);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	ast_sorcery_apply_config(sorcery, "res_pjsip_pubsub");
@@ -5249,7 +5249,7 @@ static int load_module(void)
 		ast_log(LOG_ERROR, "Could not register subscription persistence object support\n");
 		ast_sip_unregister_service(&pubsub_module);
 		ast_sched_context_destroy(sched);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_sorcery_object_field_register(sorcery, "subscription_persistence", "packet", "", OPT_CHAR_ARRAY_T, 0,
 		CHARFLDSET(struct subscription_persistence, packet));
@@ -5277,7 +5277,7 @@ static int load_module(void)
 	if (apply_list_configuration(sorcery)) {
 		ast_sip_unregister_service(&pubsub_module);
 		ast_sched_context_destroy(sched);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	ast_sorcery_apply_default(sorcery, "inbound-publication", "config", "pjsip.conf,criteria=type=inbound-publication");
@@ -5286,7 +5286,7 @@ static int load_module(void)
 		ast_log(LOG_ERROR, "Could not register subscription persistence object support\n");
 		ast_sip_unregister_service(&pubsub_module);
 		ast_sched_context_destroy(sched);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_sorcery_object_field_register(sorcery, "inbound-publication", "type", "", OPT_NOOP_T, 0, 0);
 	ast_sorcery_object_field_register_custom(sorcery, "inbound-publication", "endpoint", "",
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index 7c861dac916780fb8da3976e36284d695e5d4a74..dfa6957c7007fd29dc14d738a3240e7b933519ff 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -1650,7 +1650,7 @@ static int load_module(void)
 end:
 	unload_module();
 
-	return AST_MODULE_LOAD_FAILURE;
+	return AST_MODULE_LOAD_DECLINE;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP SDP RTP/AVP stream handler",
diff --git a/res/res_pjsip_send_to_voicemail.c b/res/res_pjsip_send_to_voicemail.c
index bd70bcfd70fc06e78ff6b502c31ed92a146d0136..1cd28ceac8f83df50b54bffab60ca8afe4241e85 100644
--- a/res/res_pjsip_send_to_voicemail.c
+++ b/res/res_pjsip_send_to_voicemail.c
@@ -219,7 +219,7 @@ static int load_module(void)
 
 	if (ast_sip_session_register_supplement(&refer_supplement)) {
 		ast_log(LOG_ERROR, "Unable to register Send to Voicemail supplement\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c
index bae4ff1dcaf7e66ec081770ee151171e4858fb18..4f082d714447951459c93cfeb004709ab9a1c5d9 100644
--- a/res/res_pjsip_t38.c
+++ b/res/res_pjsip_t38.c
@@ -938,7 +938,7 @@ static int load_module(void)
 end:
 	unload_module();
 
-	return AST_MODULE_LOAD_FAILURE;
+	return AST_MODULE_LOAD_DECLINE;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP T.38 UDPTL Support",
diff --git a/res/res_smdi.c b/res/res_smdi.c
index 4c7a45164c29357f4364434bac4166ba61107a7c..e2e5b17babfa04a4fbcf7ada9c61f687e41d9fd9 100644
--- a/res/res_smdi.c
+++ b/res/res_smdi.c
@@ -1126,7 +1126,7 @@ static int smdi_load(int reload)
 	if (!AST_LIST_EMPTY(&mwi_monitor.mailbox_mappings) && mwi_monitor.thread == AST_PTHREADT_NULL
 		&& ast_pthread_create_background(&mwi_monitor.thread, NULL, mwi_monitor_handler, NULL)) {
 		ast_log(LOG_ERROR, "Failed to start MWI monitoring thread.  This module will not operate.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return -1;
 	}
 
 	if (ao2_container_count(new_ifaces)) {
@@ -1369,7 +1369,7 @@ static int load_module(void)
 	res = smdi_load(0);
 	if (res < 0) {
 		_unload_module(1);
-		return res;
+		return AST_MODULE_LOAD_DECLINE;
 	} else if (res == 1) {
 		_unload_module(1);
 		ast_log(LOG_NOTICE, "No SMDI interfaces are available to listen on, not starting SMDI listener.\n");
diff --git a/res/res_stasis.c b/res/res_stasis.c
index 196720984ceaabd9acd675c52de07b4ee5ddcc07..9ea0d63fea0bee8e947ab8d6c269d57d46a30a10 100644
--- a/res/res_stasis.c
+++ b/res/res_stasis.c
@@ -2111,12 +2111,12 @@ static int load_module(void)
 		37, bridges_channel_hash_fn, bridges_channel_sort_fn, NULL);
 	if (!apps_registry || !app_controls || !app_bridges || !app_bridges_moh || !app_bridges_playback) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (messaging_init()) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	bridge_stasis_init();
diff --git a/res/res_stasis_device_state.c b/res/res_stasis_device_state.c
index e16bd8edddd6e38f5f3940d73fd9882652a8d0bd..344cb40c96ad663c1896822de2c35659fa32fdb0 100644
--- a/res/res_stasis_device_state.c
+++ b/res/res_stasis_device_state.c
@@ -453,13 +453,14 @@ static int load_module(void)
 	populate_cache();
 	if (ast_devstate_prov_add(DEVICE_STATE_PROVIDER_STASIS,
 				  stasis_device_state_cb)) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(device_state_subscriptions = ao2_container_alloc(
 		      DEVICE_STATE_BUCKETS, device_state_subscriptions_hash,
 		      device_state_subscriptions_cmp))) {
-		return AST_MODULE_LOAD_FAILURE;
+		ast_devstate_prov_del(DEVICE_STATE_PROVIDER_STASIS);
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	stasis_app_register_event_source(&device_state_event_source);
diff --git a/res/res_stasis_playback.c b/res/res_stasis_playback.c
index 4370f17121ddfd4ea851daefdfccd855097af601..c6f21365bd72de3d38f8741436e93238bac8c205 100644
--- a/res/res_stasis_playback.c
+++ b/res/res_stasis_playback.c
@@ -731,13 +731,14 @@ static int load_module(void)
 
 	r = STASIS_MESSAGE_TYPE_INIT(stasis_app_playback_snapshot_type);
 	if (r != 0) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	playbacks = ao2_container_alloc(PLAYBACK_BUCKETS, playback_hash,
 		playback_cmp);
 	if (!playbacks) {
-		return AST_MODULE_LOAD_FAILURE;
+		STASIS_MESSAGE_TYPE_CLEANUP(stasis_app_playback_snapshot_type);
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
diff --git a/res/res_stasis_recording.c b/res/res_stasis_recording.c
index 630205c34d5cd378dfb4df6d74d8b08ac86c9b94..56984cb4016c5c72465f85c33e2e87d63d6881ec 100644
--- a/res/res_stasis_recording.c
+++ b/res/res_stasis_recording.c
@@ -631,13 +631,14 @@ static int load_module(void)
 
 	r = STASIS_MESSAGE_TYPE_INIT(stasis_app_recording_snapshot_type);
 	if (r != 0) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	recordings = ao2_container_alloc(RECORDING_BUCKETS, recording_hash,
 		recording_cmp);
 	if (!recordings) {
-		return AST_MODULE_LOAD_FAILURE;
+		STASIS_MESSAGE_TYPE_CLEANUP(stasis_app_recording_snapshot_type);
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
diff --git a/res/res_stasis_test.c b/res/res_stasis_test.c
index 8b5bad7aea221e3ec126f3b60416171a52846eb8..19d2a42c6af25087a9fc73c29e22df4724992e07 100644
--- a/res/res_stasis_test.c
+++ b/res/res_stasis_test.c
@@ -272,7 +272,7 @@ static int unload_module(void)
 static int load_module(void)
 {
 	if (STASIS_MESSAGE_TYPE_INIT(stasis_test_message_type) != 0) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/res/res_statsd.c b/res/res_statsd.c
index 22c4ba2e700075180966d48b32fcef0a33ccb15d..3d7dd168400f980c1a80c90ddeff599e746712e9 100644
--- a/res/res_statsd.c
+++ b/res/res_statsd.c
@@ -349,7 +349,8 @@ static int load_module(void)
 	}
 
 	if (statsd_init() != 0) {
-		return AST_MODULE_LOAD_FAILURE;
+		aco_info_destroy(&cfg_info);
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/rest-api-templates/res_ari_resource.c.mustache b/rest-api-templates/res_ari_resource.c.mustache
index c28a62cd9ec45626ffda41a7b0e3d47adb5494c8..ca4e2f192a3611cd232a7a0188deabc172fce119 100644
--- a/rest-api-templates/res_ari_resource.c.mustache
+++ b/rest-api-templates/res_ari_resource.c.mustache
@@ -256,6 +256,19 @@ fin: __attribute__((unused))
 {{> rest_handler}}
 {{/root_path}}
 
+static int unload_module(void)
+{
+	ast_ari_remove_handler(&{{root_full_name}});
+{{#apis}}
+{{#has_websocket}}
+	ao2_cleanup({{full_name}}.ws_server);
+	{{full_name}}.ws_server = NULL;
+{{/has_websocket}}
+{{/apis}}
+	stasis_app_unref();
+	return 0;
+}
+
 static int load_module(void)
 {
 	int res = 0;
@@ -270,14 +283,14 @@ static int load_module(void)
 
 	{{full_name}}.ws_server = ast_websocket_server_create();
 	if (!{{full_name}}.ws_server) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	protocol = ast_websocket_sub_protocol_alloc("{{websocket_protocol}}");
 	if (!protocol) {
 		ao2_ref({{full_name}}.ws_server, -1);
 		{{full_name}}.ws_server = NULL;
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	protocol->session_attempted = ast_ari_{{c_name}}_{{c_nickname}}_ws_attempted_cb;
 	protocol->session_established = ast_ari_{{c_name}}_{{c_nickname}}_ws_established_cb;
@@ -289,21 +302,12 @@ static int load_module(void)
 {{/apis}}
 	stasis_app_ref();
 	res |= ast_ari_add_handler(&{{root_full_name}});
-	return res;
-}
+	if (res) {
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
+	}
 
-static int unload_module(void)
-{
-	ast_ari_remove_handler(&{{root_full_name}});
-{{#apis}}
-{{#has_websocket}}
-	ao2_cleanup({{full_name}}.ws_server);
-	{{full_name}}.ws_server = NULL;
-	ast_ari_websocket_events_event_websocket_dtor();
-{{/has_websocket}}
-{{/apis}}
-	stasis_app_unref();
-	return 0;
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - {{{description}}}",
diff --git a/tests/test_bucket.c b/tests/test_bucket.c
index 2b6e059c37098c9ea83188424302fa4fd77827d1..2cf5267c134f94db7c86d8b358a4fa7f531740b5 100644
--- a/tests/test_bucket.c
+++ b/tests/test_bucket.c
@@ -1012,7 +1012,7 @@ static int load_module(void)
 	if (ast_bucket_scheme_register("test", &bucket_test_wizard, &bucket_file_test_wizard,
 		ast_bucket_file_temporary_create, ast_bucket_file_temporary_destroy)) {
 		ast_log(LOG_ERROR, "Failed to register Bucket test wizard scheme implementation\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	AST_TEST_REGISTER(bucket_scheme_register);
diff --git a/tests/test_channel_feature_hooks.c b/tests/test_channel_feature_hooks.c
index c9fdf098377fcfa87a5bec3a0e5690b2cadb3674..a325484587e5ed65d0c57a09dda7394fada96a65 100644
--- a/tests/test_channel_feature_hooks.c
+++ b/tests/test_channel_feature_hooks.c
@@ -345,7 +345,7 @@ static int load_module(void)
 {
 	test_features_chan_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
 	if (!test_features_chan_tech.capabilities) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append(test_features_chan_tech.capabilities, TEST_CHANNEL_FORMAT, 0);
 	ast_channel_register(&test_features_chan_tech);