immich-app/immich · warning · NotFoundException
Asset not found or metadata not yet ready for streaming
Error message
Asset not found or metadata not yet ready for streaming
What it means
When a client requests a media (variant) playlist via getMediaPlaylist, the service calls videoStreamRepository.getForMediaPlaylist(assetId, sessionId). A null result means either the asset was deleted, the asset has not yet had its streaming metadata prepared, or the provided sessionId does not match a known session for the asset. Because all three collapse into null, Immich throws 404 with a combined message.
Source
Thrown at server/src/services/hls.service.ts:74
throw new NotFoundException('Asset metadata is not yet ready for streaming');
}
// Sharing the sessionId allows only one microservices worker to successfully insert to the session table.
// The microservices worker that creates a session owns the transcoding lifecycle for it.
const sessionId = this.cryptoRepository.randomUUID();
this.websocketRepository.serverSend('HlsSessionRequest', { sessionId, assetId, ownerId: auth.user.id });
await this.pendingSessions.wait(sessionId);
this.trackSession(sessionId);
return this.generateMainPlaylist(sessionId, ffmpeg, asset);
}
async getMediaPlaylist(auth: AuthDto, assetId: string, sessionId: string, variantIndex: number, position?: number) {
await this.requireAccess({ auth, permission: Permission.AssetView, ids: [assetId] });
const asset = await this.videoStreamRepository.getForMediaPlaylist(assetId, sessionId);
if (!asset) {
throw new NotFoundException('Asset not found or metadata not yet ready for streaming');
}
const segmentation = this.getSegmentation(asset);
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] });View on GitHub (pinned to 199723261c)
Solutions
- Re-fetch the main playlist to obtain a fresh sessionId, then request the media playlist again.
- If the asset was just uploaded, wait for metadata/segment jobs to finish then retry.
- Confirm the asset still exists (GET /assets/{id}); if 404, stop playback.
- Ensure microservices are running so session/variant metadata gets produced promptly.
Defensive patterns
Strategy: retry
Validate before calling
// always derive sessionId from a fresh main playlist call const main = await api.hlsApi.getMainPlaylist(auth, assetId); const sessionId = parseSessionId(main); // valid before requesting media playlist await api.hlsApi.getMediaPlaylist(auth, assetId, sessionId, variantIndex);
Type guard
const isValidSession = (s: string | undefined): s is string => typeof s === 'string' && s.length > 0;
Try / catch
try {
await api.hlsApi.getMediaPlaylist(auth, assetId, sessionId, variantIndex);
} catch (e) {
if (e.status === 404) {
// refresh main playlist and retry once with a new session
const main = await api.hlsApi.getMainPlaylist(auth, assetId);
return api.hlsApi.getMediaPlaylist(auth, assetId, parseSessionId(main), variantIndex);
}
throw e;
} Prevention
- Never cache sessionId longer than the playback session.
- Handle 404 by re-fetching the main playlist.
- Confirm microservices are running for timely variant metadata.
When it happens
Trigger: GET /assets/{id}/video/playlists/media.m3u8?sessionId=...&variantIndex=... where the asset is gone, its media-playlist data isn't ready, or the sessionId is stale/wrong. Common right after the main playlist was generated but before the worker produced variant metadata, or when a stale player retries after session expiry.
Common situations: Player holding a sessionId after the HLS session was closed; race during initial segment generation; asset deleted while someone was watching; microservices lag.
Related errors
- Asset metadata is not yet ready for streaming
- Session not found
- No supported variants for this video
- Real-time transcoding is not enabled
- Asset not found or asset is not a video
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/a8ec1ca241996ce4.
Report an issue: GitHub.