diff --git a/main/media_cache.c b/main/media_cache.c
index 1f81e3ae1ade4931575f9d136dbce42153020efd..9d68a10a54e37f27289d4312981fdc9c7f0e9672 100644
--- a/main/media_cache.c
+++ b/main/media_cache.c
@@ -189,23 +189,31 @@ static void media_cache_item_del_from_astdb(struct ast_bucket_file *bucket_file)
 static void bucket_file_update_path(struct ast_bucket_file *bucket_file,
 	const char *preferred_file_name)
 {
-	if (ast_strlen_zero(preferred_file_name)) {
-		return;
-	}
+	char *ext;
 
-	if (!strcmp(bucket_file->path, preferred_file_name)) {
-		return;
-	}
+	if (!ast_strlen_zero(preferred_file_name) && strcmp(bucket_file->path, preferred_file_name)) {
+		/* Use the preferred file name if available */
+
+		rename(bucket_file->path, preferred_file_name);
+		ast_copy_string(bucket_file->path, preferred_file_name,
+			sizeof(bucket_file->path));
+	} else if (!strchr(bucket_file->path, '.') && (ext = strrchr(ast_sorcery_object_get_id(bucket_file), '.'))) {
+		/* If we don't have a file extension and were provided one in the URI, use it */
+		char new_path[PATH_MAX];
+
+		ast_bucket_file_metadata_set(bucket_file, "ext", ext);
 
-	rename(bucket_file->path, preferred_file_name);
-	ast_copy_string(bucket_file->path, preferred_file_name,
-		sizeof(bucket_file->path));
+		snprintf(new_path, sizeof(new_path), "%s%s", bucket_file->path, ext);
+		rename(bucket_file->path, new_path);
+		ast_copy_string(bucket_file->path, new_path, sizeof(bucket_file->path));
+	}
 }
 
 int ast_media_cache_retrieve(const char *uri, const char *preferred_file_name,
 	char *file_path, size_t len)
 {
 	struct ast_bucket_file *bucket_file;
+	char *ext;
 	SCOPED_AO2LOCK(media_lock, media_cache);
 
 	if (ast_strlen_zero(uri)) {
@@ -220,11 +228,18 @@ int ast_media_cache_retrieve(const char *uri, const char *preferred_file_name,
 	if (bucket_file) {
 		if (!ast_bucket_file_is_stale(bucket_file)) {
 			ast_copy_string(file_path, bucket_file->path, len);
+			if ((ext = strrchr(file_path, '.'))) {
+				*ext = '\0';
+			}
 			ao2_ref(bucket_file, -1);
+
+			ast_debug(5, "Returning media at local file: %s\n", file_path);
 			return 0;
 		}
 
-		/* Stale! Drop the ref, as we're going to retrieve it next. */
+		/* Stale! Remove the item completely, as we're going to replace it next */
+		ao2_unlink_flags(media_cache, bucket_file, OBJ_NOLOCK);
+		ast_bucket_file_delete(bucket_file);
 		ao2_ref(bucket_file, -1);
 	}
 
@@ -243,9 +258,14 @@ int ast_media_cache_retrieve(const char *uri, const char *preferred_file_name,
 	bucket_file_update_path(bucket_file, preferred_file_name);
 	media_cache_item_sync_to_astdb(bucket_file);
 	ast_copy_string(file_path, bucket_file->path, len);
+	if ((ext = strrchr(file_path, '.'))) {
+		*ext = '\0';
+	}
 	ao2_link_flags(media_cache, bucket_file, OBJ_NOLOCK);
 	ao2_ref(bucket_file, -1);
 
+	ast_debug(5, "Returning media at local file: %s\n", file_path);
+
 	return 0;
 }
 
@@ -692,7 +712,7 @@ int ast_media_cache_init(void)
 {
 	ast_register_atexit(media_cache_shutdown);
 
-	media_cache = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, AO2_BUCKETS,
+	media_cache = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_MUTEX, AO2_BUCKETS,
 		media_cache_hash, media_cache_cmp);
 	if (!media_cache) {
 		return -1;