immich-app/immich · error · NotFoundException
Session not found
Error message
Session not found
What it means
Guard in getSegment: the requested HLS session id has no entry in the video stream session table. Sessions are created by the owning transcoding worker and expire or are removed when transcoding stops, so a stale or unknown session id (expired playback, worker restart, forged id) yields a 404 before serving the segment.
Solutions
- Let the player restart playback from the main playlist to obtain a fresh session
- Verify the sessionId came from a recent getMainPlaylist/getMediaPlaylist response
- Ensure the transcoding worker and session store share state and cleanup timing
- Reject stale sessions client-side and re-request the stream
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at server/src/services/hls.service.ts:96 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/d6cb3b623718fa6f.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/hls.service.ts:96
const hintedSegment = position === undefined ? undefined : this.positionToSegmentIndex(segmentation, position);
this.prewarmVariant(assetId, sessionId, variantIndex, hintedSegment);
return this.generateMediaPlaylist(asset, segmentation);
}
async getSegment(
auth: AuthDto,
assetId: string,
sessionId: string,
variantIndex: number,
filename: string,
initSegment?: number,
) {
await this.requireAccess({ auth, permission: Permission.AssetView, ids: [assetId] });
const session = await this.videoStreamRepository.getSession(sessionId);
if (!session) {
throw new NotFoundException('Session not found');
}
const variantDir = StorageCore.getHlsVariantFolder({ ownerId: auth.user.id, sessionId, variantIndex });
const path = join(variantDir, filename);
const response = new ImmichFileResponse({
path,
contentType: 'video/mp4',
cacheControl: CacheControl.PrivateWithCache,
});
const apiSession = this.trackSession(sessionId, variantIndex);
const segmentIndex = this.getSegmentIndex(apiSession, filename, initSegment);
this.websocketRepository.serverSend('HlsHeartbeat', { sessionId, variantIndex, segmentIndex });
if (await this.storageRepository.checkFileExists(path, constants.R_OK)) {
return response;
}
View on GitHub (pinned to e55ac299a4)