diff --git a/api/funkwhale_api/music/management/commands/fix_track_files.py b/api/funkwhale_api/music/management/commands/fix_track_files.py
index f68bcf1359d4661710a98ee443ff1578824f46f2..9adc1b9bf1a9d24f3cb26b6da4dce68dc6078213 100644
--- a/api/funkwhale_api/music/management/commands/fix_track_files.py
+++ b/api/funkwhale_api/music/management/commands/fix_track_files.py
@@ -2,6 +2,7 @@ import cacheops
 import os
 
 from django.db import transaction
+from django.db.models import Q
 from django.conf import settings
 from django.core.management.base import BaseCommand, CommandError
 
@@ -24,6 +25,8 @@ class Command(BaseCommand):
         if options['dry_run']:
             self.stdout.write('Dry-run on, will not commit anything')
         self.fix_mimetypes(**options)
+        self.fix_file_data(**options)
+        self.fix_file_size(**options)
         cacheops.invalidate_model(models.TrackFile)
 
     @transaction.atomic
@@ -43,3 +46,60 @@ class Command(BaseCommand):
             if not dry_run:
                 self.stdout.write('[mimetypes] commiting...')
                 qs.update(mimetype=mimetype)
+
+    def fix_file_data(self, dry_run, **kwargs):
+        self.stdout.write('Fixing missing bitrate or length...')
+        matching = models.TrackFile.objects.filter(
+            Q(bitrate__isnull=True) | Q(duration__isnull=True))
+        total = matching.count()
+        self.stdout.write(
+            '[bitrate/length] {} entries found with missing values'.format(
+                total))
+        if dry_run:
+            return
+        for i, tf in enumerate(matching.only('audio_file')):
+            self.stdout.write(
+                '[bitrate/length] {}/{} fixing file #{}'.format(
+                    i+1, total, tf.pk
+                ))
+
+            try:
+                audio_file = tf.get_audio_file()
+                if audio_file:
+                    with audio_file as f:
+                        data = utils.get_audio_file_data(audio_file)
+                    tf.bitrate = data['bitrate']
+                    tf.duration = data['length']
+                    tf.save(update_fields=['duration', 'bitrate'])
+                else:
+                    self.stderr.write('[bitrate/length] no file found')
+            except Exception as e:
+                self.stderr.write(
+                    '[bitrate/length] error with file #{}: {}'.format(
+                        tf.pk, str(e)
+                    )
+                )
+
+    def fix_file_size(self, dry_run, **kwargs):
+        self.stdout.write('Fixing missing size...')
+        matching = models.TrackFile.objects.filter(size__isnull=True)
+        total = matching.count()
+        self.stdout.write(
+            '[size] {} entries found with missing values'.format(total))
+        if dry_run:
+            return
+        for i, tf in enumerate(matching.only('size')):
+            self.stdout.write(
+                '[size] {}/{} fixing file #{}'.format(
+                    i+1, total, tf.pk
+                ))
+
+            try:
+                tf.size = tf.get_file_size()
+                tf.save(update_fields=['size'])
+            except Exception as e:
+                self.stderr.write(
+                    '[size] error with file #{}: {}'.format(
+                        tf.pk, str(e)
+                    )
+                )
diff --git a/api/tests/music/test_commands.py b/api/tests/music/test_commands.py
new file mode 100644
index 0000000000000000000000000000000000000000..ff3343aa53fd13be34c99316c2da38c188571e93
--- /dev/null
+++ b/api/tests/music/test_commands.py
@@ -0,0 +1,45 @@
+from funkwhale_api.music.management.commands import fix_track_files
+
+
+def test_fix_track_files_bitrate_length(factories, mocker):
+    tf1 = factories['music.TrackFile'](bitrate=1, duration=2)
+    tf2 = factories['music.TrackFile'](bitrate=None, duration=None)
+    c = fix_track_files.Command()
+
+    mocker.patch(
+        'funkwhale_api.music.utils.get_audio_file_data',
+        return_value={'bitrate': 42, 'length': 43})
+
+    c.fix_file_data(dry_run=False)
+
+    tf1.refresh_from_db()
+    tf2.refresh_from_db()
+
+    # not updated
+    assert tf1.bitrate == 1
+    assert tf1.duration == 2
+
+    # updated
+    assert tf2.bitrate == 42
+    assert tf2.duration == 43
+
+
+def test_fix_track_files_size(factories, mocker):
+    tf1 = factories['music.TrackFile'](size=1)
+    tf2 = factories['music.TrackFile'](size=None)
+    c = fix_track_files.Command()
+
+    mocker.patch(
+        'funkwhale_api.music.models.TrackFile.get_file_size',
+        return_value=2)
+
+    c.fix_file_size(dry_run=False)
+
+    tf1.refresh_from_db()
+    tf2.refresh_from_db()
+
+    # not updated
+    assert tf1.size == 1
+
+    # updated
+    assert tf2.size == 2