diff --git a/api/funkwhale_api/music/models.py b/api/funkwhale_api/music/models.py
index 309eb1266dd5fd8db1446ff8981a89de4a1fecf9..cf6a0b7ba310cbbe7354a20072de3a6f352333e4 100644
--- a/api/funkwhale_api/music/models.py
+++ b/api/funkwhale_api/music/models.py
@@ -870,7 +870,14 @@ class UploadVersion(models.Model):
 
     @property
     def filename(self):
-        return self.upload.filename
+        try:
+            return (
+                self.upload.track.full_name
+                + "."
+                + utils.MIMETYPE_TO_EXTENSION[self.mimetype]
+            )
+        except KeyError:
+            return self.upload.filename
 
     @property
     def audio_file_path(self):
diff --git a/api/funkwhale_api/music/views.py b/api/funkwhale_api/music/views.py
index 391a4b333fe45628626383c4479d4a952c9df4b5..4f8f35ced2b2e7a0f6319b568fad511fb48dd711 100644
--- a/api/funkwhale_api/music/views.py
+++ b/api/funkwhale_api/music/views.py
@@ -285,6 +285,11 @@ def should_transcode(upload, format, max_bitrate=None):
     return format_need_transcoding or bitrate_need_transcoding
 
 
+def get_content_disposition(filename):
+    filename = "filename*=UTF-8''{}".format(urllib.parse.quote(filename))
+    return "attachment; {}".format(filename)
+
+
 def handle_serve(upload, user, format=None, max_bitrate=None, proxy_media=True):
     f = upload
     # we update the accessed_date
@@ -342,8 +347,7 @@ def handle_serve(upload, user, format=None, max_bitrate=None, proxy_media=True):
     mapping = {"nginx": "X-Accel-Redirect", "apache2": "X-Sendfile"}
     file_header = mapping[settings.REVERSE_PROXY_TYPE]
     response[file_header] = file_path
-    filename = "filename*=UTF-8''{}".format(urllib.parse.quote(filename))
-    response["Content-Disposition"] = "attachment; {}".format(filename)
+    response["Content-Disposition"] = get_content_disposition(filename)
     if mt:
         response["Content-Type"] = mt
 
diff --git a/api/tests/music/test_views.py b/api/tests/music/test_views.py
index 102b5a790a82d8d6fc174df72b414d0bf64033bf..25845e738b228b1b1e969c04070f2de134d454eb 100644
--- a/api/tests/music/test_views.py
+++ b/api/tests/music/test_views.py
@@ -1,6 +1,7 @@
 import io
 import magic
 import os
+import urllib.parse
 
 import pytest
 from django.urls import reverse
@@ -412,7 +413,7 @@ def test_handle_serve_create_mp3_version(factories, now):
     user = factories["users.User"]()
     upload = factories["music.Upload"](bitrate=42)
     response = views.handle_serve(upload, user, format="mp3")
-
+    expected_filename = upload.track.full_name + ".mp3"
     version = upload.versions.latest("id")
 
     assert version.mimetype == "audio/mpeg"
@@ -421,7 +422,9 @@ def test_handle_serve_create_mp3_version(factories, now):
     assert version.audio_file_path.endswith(".mp3")
     assert version.size == version.audio_file.size
     assert magic.from_buffer(version.audio_file.read(), mime=True) == "audio/mpeg"
-
+    assert response["Content-Disposition"] == "attachment; filename*=UTF-8''{}".format(
+        urllib.parse.quote(expected_filename)
+    )
     assert response.status_code == 200
 
 
diff --git a/changes/changelog.d/848.bugfix b/changes/changelog.d/848.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..478a8d42cc1fc6dbcf217a0bdb1721146c6744a4
--- /dev/null
+++ b/changes/changelog.d/848.bugfix
@@ -0,0 +1 @@
+Fixed invalid file extension for transcoded tracks (#848)