immich-app/immich · error · NotFoundException
No supported variants for this video
Error message
No supported variants for this video
What it means
Raised in generateMainPlaylist while building the master m3u8: none of the configured HLS_VARIANTS survived filtering against the ffmpeg-reported supported video codecs and resolutions, or against the target resolution derived from the source video. This means the installed ffmpeg build lacks the required encoders or the source resolution is below every variant's minimum, so no playable playlist can be generated.
Solutions
- Install/enable an ffmpeg build supporting the codecs (e.g. h264/hevc) required by HLS_VARIANTS
- Add lower-resolution variants to HLS_VARIANTS so small videos match at least one
- Log the ffmpeg realtime codec/resolution capabilities to diagnose mismatches
- Fail playback setup with a clear user-facing error that the video format is unsupported
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at server/src/services/hls.service.ts:149 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/87abadcfd0183659.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/hls.service.ts:149
const targetResolution = Math.max(sourceResolution, HLS_VARIANTS[0].resolution);
const lines = ['#EXTM3U', `#EXT-X-VERSION:${HLS_VERSION}`, '#EXT-X-INDEPENDENT-SEGMENTS'];
const { videoCodecs, resolutions } = ffmpeg.realtime;
for (let i = 0; i < HLS_VARIANTS.length; i++) {
const { resolution, bitrate, codec } = HLS_VARIANTS[i];
if (resolution > targetResolution || !videoCodecs.includes(codec) || !resolutions.includes(resolution)) {
continue;
}
const { width, height } = getOutputSize(asset.videoStream, resolution);
const codecString = getCodecString(codec, width, height, fps);
lines.push(
`#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}`,
`${sessionId}/${i}/playlist.m3u8`,
);
}
lines.push('');
if (lines.length === 4) {
throw new NotFoundException('No supported variants for this video');
}
return lines.join('\n');
}
private getSegmentation({ videoStream, packets }: AssetWithStreamInfo): Segmentation {
const fps = (packets.packetCount * videoStream.timeBase) / packets.totalDuration;
const framesPerSegment = Math.ceil(HLS_SEGMENT_DURATION * fps);
const segmentCount = Math.ceil(packets.outputFrames / framesPerSegment);
return { fps, framesPerSegment, segmentCount, segmentDuration: framesPerSegment / fps };
}
private positionToSegmentIndex({ segmentDuration, segmentCount }: Segmentation, position: number) {
return Math.min(Math.max(Math.floor(position / segmentDuration), 0), segmentCount - 1);
}
private generateMediaPlaylist({ packets }: AssetWithStreamInfo, segmentation: Segmentation) {
const { fps, framesPerSegment, segmentCount, segmentDuration: fullSegmentDuration } = segmentation;View on GitHub (pinned to e55ac299a4)