diff --git a/Jellyfin.Server/Migrations/Routines/FixLibrarySubtitleDownloadLanguages.cs b/Jellyfin.Server/Migrations/Routines/FixLibrarySubtitleDownloadLanguages.cs
new file mode 100644
index 0000000000..e82123e5ac
--- /dev/null
+++ b/Jellyfin.Server/Migrations/Routines/FixLibrarySubtitleDownloadLanguages.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Jellyfin.Server.ServerSetupApp;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Globalization;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Logging;
+
+namespace Jellyfin.Server.Migrations.Routines;
+
+///
+/// Migration to fix broken library subtitle download languages.
+///
+[JellyfinMigration("2026-02-06T20:00:00", nameof(FixLibrarySubtitleDownloadLanguages))]
+internal class FixLibrarySubtitleDownloadLanguages : IAsyncMigrationRoutine
+{
+ private readonly ILocalizationManager _localizationManager;
+ private readonly ILibraryManager _libraryManager;
+ private readonly ILogger _logger;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Localization manager.
+ /// The startup logger for Startup UI integration.
+ /// The Library manager.
+ /// The logger.
+ public FixLibrarySubtitleDownloadLanguages(
+ ILocalizationManager localizationManager,
+ IStartupLogger startupLogger,
+ ILibraryManager libraryManager,
+ ILogger logger)
+ {
+ _localizationManager = localizationManager;
+ _libraryManager = libraryManager;
+ _logger = startupLogger.With(logger);
+ }
+
+ ///
+ public Task PerformAsync(CancellationToken cancellationToken)
+ {
+ _logger.LogInformation("Starting to fix library subtitle download languages.");
+
+ var virtualFolders = _libraryManager.GetVirtualFolders(false);
+
+ foreach (var virtualFolder in virtualFolders)
+ {
+ var options = virtualFolder.LibraryOptions;
+ if (options.SubtitleDownloadLanguages is null || options.SubtitleDownloadLanguages.Length == 0)
+ {
+ continue;
+ }
+
+ // Some virtual folders don't have a proper item id.
+ if (!Guid.TryParse(virtualFolder.ItemId, out var folderId))
+ {
+ continue;
+ }
+
+ var collectionFolder = _libraryManager.GetItemById(folderId);
+ if (collectionFolder is null)
+ {
+ _logger.LogWarning("Could not find collection folder for virtual folder '{LibraryName}' with id '{FolderId}'. Skipping.", virtualFolder.Name, folderId);
+ continue;
+ }
+
+ var fixedLanguages = new List();
+
+ foreach (var language in options.SubtitleDownloadLanguages)
+ {
+ var foundLanguage = _localizationManager.FindLanguageInfo(language)?.ThreeLetterISOLanguageName;
+ if (foundLanguage is not null)
+ {
+ // Converted ISO 639-2/B to T (ger to deu)
+ if (!string.Equals(foundLanguage, language, StringComparison.OrdinalIgnoreCase))
+ {
+ _logger.LogInformation("Converted '{Language}' to '{ResolvedLanguage}' in library '{LibraryName}'.", language, foundLanguage, virtualFolder.Name);
+ }
+
+ if (fixedLanguages.Contains(foundLanguage, StringComparer.OrdinalIgnoreCase))
+ {
+ _logger.LogInformation("Language '{Language}' already exists for library '{LibraryName}'. Skipping duplicate.", foundLanguage, virtualFolder.Name);
+ continue;
+ }
+
+ fixedLanguages.Add(foundLanguage);
+ }
+ else
+ {
+ _logger.LogInformation("Could not resolve language '{Language}' in library '{LibraryName}'. Skipping.", language, virtualFolder.Name);
+ }
+ }
+
+ options.SubtitleDownloadLanguages = [.. fixedLanguages];
+ collectionFolder.UpdateLibraryOptions(options);
+ }
+
+ _logger.LogInformation("Library subtitle download languages fixed.");
+
+ return Task.CompletedTask;
+ }
+}