m1k1o/neko · error
timeouted while waiting for first image
Error message
timeouted while waiting for first image
What it means
createPipeline waits up to 1 second (time.After) for the first image on the pipeline's Sample() channel. If no sample arrives within that window, it returns 'timeouted while waiting for first image'. The library uses this bounded wait so a broken/silent capture source cannot block startup forever.
Source
Thrown at server/internal/capture/screencast.go:208
if err != nil {
return err
}
manager.pipeline.AttachAppsink("appsink")
manager.pipeline.Play()
manager.pipelinesCounter.Inc()
manager.pipelinesActive.Set(1)
// get first image
select {
case image, ok := <-manager.pipeline.Sample():
if !ok {
return errors.New("unable to get first image")
} else {
manager.setImage(image)
}
case <-time.After(1 * time.Second):
return errors.New("timeouted while waiting for first image")
}
pipeline := manager.pipeline
manager.wg.Go(func() {
manager.logger.Debug().Msg("started receiving images")
for {
image, ok := <-pipeline.Sample()
if !ok {
manager.logger.Debug().Msg("stopped receiving images")
return
}
manager.setImage(image)
}
})
return nilView on GitHub (pinned to b0f01cedea)
Solutions
- Retry start — under load the first frame may simply be slow; consider increasing the 1s timeout in a fork/patch
- Validate the GStreamer pipeline string (caps, framerate, encoder) produces samples with gst-launch
- Check the display/capture source is actually producing frames (not blank/locked/headless without a capture backend)
- Reduce system load or pre-warm the pipeline before the first request
Example fix
// before
case <-time.After(1 * time.Second):
return errors.New("timeouted while waiting for first image")
// after
case <-time.After(5 * time.Second): // allow slow sources to emit first frame
return errors.New("timeouted while waiting for first image") Defensive patterns
Strategy: retry
Validate before calling
// Pre-check: ensure the capture source is alive and system not overloaded before starting.
// (Library has no pre-check API; treat timeout as retryable.)
if err := checkCaptureSourceAvailable(); err != nil {
return err
} Try / catch
if err := manager.start(); err != nil {
if err.Error() == "timeouted while waiting for first image" {
// slow source: retry with longer overall budget
for i := 0; i < 3; i++ {
time.Sleep(500 * time.Millisecond)
if err = manager.start(); err == nil { break }
}
}
return err
} Prevention
- Increase the 1s first-frame timeout if sources are known to be slow
- Verify the GStreamer pipeline produces frames (framerate caps, encoder plugins installed)
- Pre-warm the pipeline at server startup rather than on first request
- Monitor system load; heavy CPU can delay the first encoded frame beyond 1s
When it happens
Trigger: The newly created GStreamer pipeline does not emit any sample within 1 second — slow source startup, encoder stalls, wrong pipeline string, or a device that produces no frames.
Common situations: Heavy load or slow machine where the encoder takes >1s to produce the first frame; misconfigured pipeline element (wrong framerate/caps) yielding no samples; headless or locked display where the capture source never emits.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- unable to get first image
- image data not found
- screencast not enabled
- listener cannot be nil
- target stream manager does not support moving listeners
AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01).
Data as JSON: /api/errors/f471ce1605b53129.
Report an issue: GitHub.