{"record":{"id":"87abadcfd0183659","repo":"immich-app/immich","slug":"no-supported-variants-for-this-video","errorCode":null,"errorMessage":"No supported variants for this video","messagePattern":"No supported variants for this video","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"server/src/services/hls.service.ts","lineNumber":149,"sourceCode":"    const targetResolution = Math.max(sourceResolution, HLS_VARIANTS[0].resolution);\n    const lines = ['#EXTM3U', `#EXT-X-VERSION:${HLS_VERSION}`, '#EXT-X-INDEPENDENT-SEGMENTS'];\n    const { videoCodecs, resolutions } = ffmpeg.realtime;\n    for (let i = 0; i < HLS_VARIANTS.length; i++) {\n      const { resolution, bitrate, codec } = HLS_VARIANTS[i];\n      if (resolution > targetResolution || !videoCodecs.includes(codec) || !resolutions.includes(resolution)) {\n        continue;\n      }\n      const { width, height } = getOutputSize(asset.videoStream, resolution);\n      const codecString = getCodecString(codec, width, height, fps);\n      lines.push(\n        `#EXT-X-STREAM-INF:BANDWIDTH=${Math.round(bitrate * 1.35)},RESOLUTION=${width}x${height},CODECS=\"${codecString},mp4a.40.2\",VIDEO-RANGE=SDR,FRAME-RATE=${roundedFps}`,\n        `${sessionId}/${i}/playlist.m3u8`,\n      );\n    }\n    lines.push('');\n\n    if (lines.length === 4) {\n      throw new NotFoundException('No supported variants for this video');\n    }\n\n    return lines.join('\\n');\n  }\n\n  private getSegmentation({ videoStream, packets }: AssetWithStreamInfo): Segmentation {\n    const fps = (packets.packetCount * videoStream.timeBase) / packets.totalDuration;\n    const framesPerSegment = Math.ceil(HLS_SEGMENT_DURATION * fps);\n    const segmentCount = Math.ceil(packets.outputFrames / framesPerSegment);\n    return { fps, framesPerSegment, segmentCount, segmentDuration: framesPerSegment / fps };\n  }\n\n  private positionToSegmentIndex({ segmentDuration, segmentCount }: Segmentation, position: number) {\n    return Math.min(Math.max(Math.floor(position / segmentDuration), 0), segmentCount - 1);\n  }\n\n  private generateMediaPlaylist({ packets }: AssetWithStreamInfo, segmentation: Segmentation) {\n    const { fps, framesPerSegment, segmentCount, segmentDuration: fullSegmentDuration } = segmentation;","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/hls.service.ts#L131-L167","documentation":"generateMainPlaylist builds one EXT-X-STREAM-INF line per transcoding resolution the asset supports; if none could be added (lines.length === 4 means only the header lines remain), it throws 404 NotFoundException 'No supported variants for this video'. This happens when the asset's video codec/stream is not compatible with any configured output variant, or the codec string/resolution computation rejected every option.","triggerScenarios":"getMainPlaylist proceeds, asset metadata exists, but every variant was skipped in the loop (e.g. continue due to codec/targetVideoCodec mismatch, an exotic codec like HEVC with no transcode target enabled, or all resolutions higher/lower than configured). Result: no stream-INF lines.","commonSituations":"Video in a codec the configured transcode stack cannot decode; targetVideoCodec misconfigured; all transcode resolutions disabled; very unusual container/codec combo.","solutions":["Review System Settings -> Video Encoding and ensure at least one targetVideoCodec is enabled that the source can be transcoded to (commonly h264).","Confirm a transcode target resolution is enabled (CONVERTED_VIDEO_FORMATS / desired resolutions).","Check the asset's actual codec via the asset metadata and install/enable the decoder (e.g. enable HEVC support in ffmpeg).","As a last resort, transcode the source file externally and re-upload it in a supported format."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check the asset's codec is supported by configured transcode targets before offering HLS\nconst cfg = await api.systemConfigApi.getConfig();\nconst supportedCodecs = cfg.ffmpeg.targetVideoCodec; // e.g. ['h264','hevc']\nconst asset = await api.assetApi.get(assetId);\nif (!supportedCodecs.includes(asset.imageCodec /* or videoCodec */)) {\n  warnUnsupportedCodec(asset);\n}","typeGuard":"const hasSupportedVariant = (asset: { videoCodec?: string }, targets: string[]) =>\n  !!asset.videoCodec && targets.includes(asset.videoCodec);","tryCatchPattern":"try {\n  await api.hlsApi.getMainPlaylist(auth, assetId);\n} catch (e) {\n  if (e.status === 404 && /No supported variants/.test(e.message)) {\n    showFallback('Direct download only - no streaming variants available for this codec');\n  } else throw e;\n}","preventionTips":["Enable at least h264 as a target transcode codec.","Keep ffmpeg decoders broad enough for source codecs (e.g. HEVC, VP9).","Offer a direct-download fallback in the player for unsupported sources."],"tags":["video","hls","transcoding","codec","ffmpeg","not-found","immich","nestjs"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}