{"record":{"id":"10f82a6bccef3658","repo":"jellyfin/jellyfin","slug":"mediasource-mediasourceid-has-no-attachment-with","errorCode":null,"errorMessage":"MediaSource {mediaSourceId} has no attachment with stream index {attachmentStreamIndex}","messagePattern":"MediaSource (.+?) has no attachment with stream index (.+?)","errorType":"http","errorClass":"ResourceNotFoundException","httpStatus":404,"severity":"error","filePath":"MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs","lineNumber":84,"sourceCode":"\n            if (string.IsNullOrWhiteSpace(mediaSourceId))\n            {\n                throw new ArgumentNullException(nameof(mediaSourceId));\n            }\n\n            var mediaSources = await _mediaSourceManager.GetPlaybackMediaSources(item, null, true, false, cancellationToken).ConfigureAwait(false);\n            var mediaSource = mediaSources\n                .FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase));\n            if (mediaSource is null)\n            {\n                throw new ResourceNotFoundException($\"MediaSource {mediaSourceId} not found\");\n            }\n\n            var mediaAttachment = mediaSource.MediaAttachments\n                .FirstOrDefault(i => i.Index == attachmentStreamIndex);\n            if (mediaAttachment is null)\n            {\n                throw new ResourceNotFoundException($\"MediaSource {mediaSourceId} has no attachment with stream index {attachmentStreamIndex}\");\n            }\n\n            if (string.Equals(mediaAttachment.Codec, \"mjpeg\", StringComparison.OrdinalIgnoreCase))\n            {\n                throw new ResourceNotFoundException($\"Attachment with stream index {attachmentStreamIndex} can't be extracted for MediaSource {mediaSourceId}\");\n            }\n\n            var attachmentStream = await GetAttachmentStream(mediaSource, mediaAttachment, cancellationToken)\n                    .ConfigureAwait(false);\n\n            return (mediaAttachment, attachmentStream);\n        }\n\n        /// <inheritdoc />\n        public async Task ExtractAllAttachments(\n            string inputFile,\n            MediaSourceInfo mediaSource,\n            CancellationToken cancellationToken)","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/jellyfin/jellyfin/blob/ae8723026d97b6d0f926638803edef338919b794/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs#L66-L102","documentation":"The media source was found, but it has no MediaAttachment entry whose Index equals the requested attachmentStreamIndex. ResourceNotFoundException maps to 404. This is distinct from [127] (no source at all): the source exists, it just lacks that attachment slot.","triggerScenarios":"mediaSource is non-null, but mediaSource.MediaAttachments.FirstOrDefault(i => i.Index == attachmentStreamIndex) returns null.","commonSituations":"Client requests an attachment index that was present in an older version of the file; the file changed since metadata was cached (attachments renumbered); the file has no embedded attachments at all but the client assumed one; metadata cache stale after remuxing.","solutions":["Refresh metadata for the item so MediaAttachments is rebuilt from the current file.","Have the client enumerate the available attachment indices from MediaSources before requesting one.","Confirm the file actually contains embedded attachments (ffprobe -attach)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify the requested attachment index exists first.\nvar attach = mediaSource.MediaAttachments.FirstOrDefault(a => a.Index == attachmentStreamIndex);\nif (attach is null) return NotFound($\"No attachment {attachmentStreamIndex}\");","typeGuard":"static bool HasAttachment(MediaSourceInfo src, int idx) =>\n    src.MediaAttachments?.Any(a => a.Index == idx) == true;","tryCatchPattern":"try { /* extract */ }\ncatch (ResourceNotFoundException ex) when (ex.Message.Contains(\"no attachment\"))\n{\n    logger.LogInformation(\"Attachment {Idx} absent on {Id}; refreshing metadata.\", idx, mediaSourceId);\n    return NotFound();\n}","preventionTips":["Enumerate MediaAttachments on the source before requesting a specific index.","Refresh metadata after remuxing/replacing a file.","Treat a missing index as a client-visible 404, not a server bug."],"tags":["media-source","attachment","media-encoding","not-found"],"backgroundTag":null,"analyzedSha":"ae8723026d97b6d0f926638803edef338919b794","analyzedAt":"2026-08-13T10:43:30.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}