diff --git a/apps/app_mixmonitor.c b/apps/app_mixmonitor.c
index e8d4903f0b1d9d4513a43811a9aba0d8ff6d0158..ea05ec32cf02e1836ca4b9ec1d1019513ef4ccda 100644
--- a/apps/app_mixmonitor.c
+++ b/apps/app_mixmonitor.c
@@ -744,6 +744,8 @@ static void *mixmonitor_thread(void *obj)
 	}
 
 	mixmonitor_free(mixmonitor);
+
+	ast_module_unref(ast_module_info->self);
 	return NULL;
 }
 
@@ -783,7 +785,7 @@ static int setup_mixmonitor_ds(struct mixmonitor *mixmonitor, struct ast_channel
 	return 0;
 }
 
-static void launch_monitor_thread(struct ast_channel *chan, const char *filename,
+static int launch_monitor_thread(struct ast_channel *chan, const char *filename,
 				  unsigned int flags, int readvol, int writevol,
 				  const char *post_process, const char *filename_write,
 				  char *filename_read, const char *uid_channel_var,
@@ -810,33 +812,33 @@ static void launch_monitor_thread(struct ast_channel *chan, const char *filename
 
 	/* Pre-allocate mixmonitor structure and spy */
 	if (!(mixmonitor = ast_calloc(1, sizeof(*mixmonitor)))) {
-		return;
+		return -1;
 	}
 
 	/* Now that the struct has been calloced, go ahead and initialize the string fields. */
 	if (ast_string_field_init(mixmonitor, 512)) {
 		mixmonitor_free(mixmonitor);
-		return;
+		return -1;
 	}
 
 	/* Setup the actual spy before creating our thread */
 	if (ast_audiohook_init(&mixmonitor->audiohook, AST_AUDIOHOOK_TYPE_SPY, mixmonitor_spy_type, 0)) {
 		mixmonitor_free(mixmonitor);
-		return;
+		return -1;
 	}
 
 	/* Copy over flags and channel name */
 	mixmonitor->flags = flags;
 	if (!(mixmonitor->autochan = ast_autochan_setup(chan))) {
 		mixmonitor_free(mixmonitor);
-		return;
+		return -1;
 	}
 
 	if (setup_mixmonitor_ds(mixmonitor, chan, &datastore_id)) {
 		ast_autochan_destroy(mixmonitor->autochan);
 		mixmonitor_free(mixmonitor);
 		ast_free(datastore_id);
-		return;
+		return -1;
 	}
 
 	if (!ast_strlen_zero(uid_channel_var)) {
@@ -905,13 +907,13 @@ static void launch_monitor_thread(struct ast_channel *chan, const char *filename
 			mixmonitor_spy_type, ast_channel_name(chan));
 		ast_audiohook_destroy(&mixmonitor->audiohook);
 		mixmonitor_free(mixmonitor);
-		return;
+		return -1;
 	}
 
 	/* reference be released at mixmonitor destruction */
 	mixmonitor->callid = ast_read_threadstorage_callid();
 
-	ast_pthread_create_detached_background(&thread, NULL, mixmonitor_thread, mixmonitor);
+	return ast_pthread_create_detached_background(&thread, NULL, mixmonitor_thread, mixmonitor);
 }
 
 /* a note on filename_parse: creates directory structure and assigns absolute path from relative paths for filenames */
@@ -1032,7 +1034,10 @@ static int mixmonitor_exec(struct ast_channel *chan, const char *data)
 	}
 
 	pbx_builtin_setvar_helper(chan, "MIXMONITOR_FILENAME", args.filename);
-	launch_monitor_thread(chan,
+
+	/* If launch_monitor_thread works, the module reference must not be released until it is finished. */
+	ast_module_ref(ast_module_info->self);
+	if (launch_monitor_thread(chan,
 			args.filename,
 			flags.flags,
 			readvol,
@@ -1041,7 +1046,9 @@ static int mixmonitor_exec(struct ast_channel *chan, const char *data)
 			filename_write,
 			filename_read,
 			uid_channel_var,
-			recipients);
+			recipients)) {
+		ast_module_unref(ast_module_info->self);
+	}
 
 	return 0;
 }