immich-app/immich · warning · NotFoundException
Asset metadata is not yet ready for streaming
Error message
Asset metadata is not yet ready for streaming
What it means
Before serving a video's main HLS playlist, Immich fetches the asset's prepared video metadata (codec, streams, packets) via videoStreamRepository.getForMainPlaylist. If that returns null - typically because metadata extraction / video probe has not completed for a freshly uploaded asset - it throws 404 NotFoundException. The asset exists and is accessible, but the data needed to plan transcoding variants is not ready yet.
Source
Thrown at server/src/services/hls.service.ts:56
this.sessions.delete(sessionId);
this.pendingSegments.rejectByPrefix(`${sessionId}:`, 'Session ended');
}
@OnEvent({ name: 'HlsSegmentResult', server: true, workers: [ImmichWorker.Api] })
onSegmentResult(event: ArgOf<'HlsSegmentResult'>) {
this.pendingSegments.complete(this.getSegmentKey(event), event);
}
async getMainPlaylist(auth: AuthDto, assetId: string) {
await this.requireAccess({ auth, permission: Permission.AssetView, ids: [assetId] });
const { ffmpeg } = await this.getConfig({ withCache: true });
if (!ffmpeg.realtime.enabled) {
throw new BadRequestException('Real-time transcoding is not enabled');
}
const asset = await this.videoStreamRepository.getForMainPlaylist(assetId);
if (!asset) {
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');View on GitHub (pinned to 199723261c)
Solutions
- Wait a few seconds and retry - the playlist becomes available once the metadata/probe job completes.
- Check the Jobs dashboard for a stuck or failed MetadataExtraction / video probe queue and re-run it for the asset.
- Confirm the microservices container/worker is running (without it the job never processes).
- If persistent, trigger metadata re-extraction for the asset from the admin maintenance menu.
Defensive patterns
Strategy: retry
Validate before calling
// check asset is ready before opening the player
const asset = await api.assetApi.get(assetId);
if (!asset?.encodedVideoPath && asset?.type === 'VIDEO') {
// metadata may still be processing - wait or show a 'preparing' state
await waitForJob('MetadataExtraction', assetId);
} Type guard
const isAssetReadyForStreaming = (a: { encodedVideoPath?: string; type: string }) =>
a.type === 'VIDEO' && !!a.encodedVideoPath; Try / catch
for (let attempt = 0; attempt < 5; attempt++) {
try {
return await api.hlsApi.getMainPlaylist(auth, assetId);
} catch (e) {
if (e.status === 404 && /not yet ready/.test(e.message)) {
await delay(2000 * (attempt + 1));
continue;
}
throw e;
}
}
throw new Error('Asset metadata never became ready'); Prevention
- Show a 'Preparing video' state in the UI for freshly uploaded videos.
- Monitor the MetadataExtraction job queue for backlogs.
- Ensure at least one microservices worker is running.
When it happens
Trigger: User opens a just-uploaded video in the viewer before the MetadataExtraction / video probe job has finished writing the stream info getForMainPlaylist needs. Asset row exists, but its videoStream/segments data is absent.
Common situations: Background jobs backlog; microservices worker not running or crashed; very large video still being probed; metadata job failed silently for that asset.
Related errors
- Asset not found or metadata 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/75d53b95babe924f.
Report an issue: GitHub.