AlexxIT/go2rtc · error

api.StreamNotFound

Error message

api.StreamNotFound

What it means

The MJPEG WebSocket handler (handlerWS) looks up the stream named by the request's query parameters via streams.GetOrPatch. If no stream with that name exists (nil result), it returns the api.StreamNotFound error, refusing to create the MJPEG consumer.

Solutions

  1. Ensure the WS URL query includes src=<existing stream name> exactly as configured
  2. Verify the stream exists in go2rtc.yaml or was created via the streams API before connecting
  3. Check for typos and case differences in the stream name
  4. Confirm go2rtc reloaded the config after adding the stream

Example fix

// before
new WebSocket("ws://host:1984/api/ws?src=camm")
// after
new WebSocket("ws://host:1984/api/ws?src=cam")
Defensive patterns

Strategy: validation

Validate before calling

// JS: verify the stream exists before opening WS/MJPEG
const res = await fetch(`http://host:1984/api/streams?src=${name}`)
if (!(await res.ok)) throw new Error(`stream ${name} not found`)
const ws = new WebSocket(`ws://host:1984/api/ws?src=${name}`)

Try / catch

// JS
ws.onerror = (e) => console.error('mjpeg ws failed — check src stream name:', e)
ws.onclose = (ev) => { if (ev.code === 1006) checkStreamExists() }

Prevention

When it happens

Trigger: Opening a WS/MJPEG connection with a ?src=name query parameter that doesn't match any configured or dynamically created stream; empty or misspelled src parameter.

Common situations: Frontend JS pointing at a stream name that was renamed or removed from go2rtc.yaml, case-sensitive name mismatch, or forgetting the src query parameter entirely.

Related errors


AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07). Data as JSON: /api/errors/13a4cf03a982855f. Report an issue: GitHub.

Appendix: source

Thrown at internal/mjpeg/mjpeg.go:196

		return
	}

	prod, _ := mpjpeg.Open(r.Body)
	prod.WithRequest(r)

	stream.AddProducer(prod)

	if err := prod.Start(); err != nil && err != io.EOF {
		log.Warn().Err(err).Caller().Send()
	}

	stream.RemoveProducer(prod)
}

func handlerWS(tr *ws.Transport, _ *ws.Message) error {
	stream, _ := streams.GetOrPatch(tr.Request.URL.Query())
	if stream == nil {
		return errors.New(api.StreamNotFound)
	}

	cons := mjpeg.NewConsumer()
	cons.WithRequest(tr.Request)

	if err := stream.AddConsumer(cons); err != nil {
		log.Debug().Err(err).Msg("[mjpeg] add consumer")
		return err
	}

	tr.Write(&ws.Message{Type: "mjpeg"})

	go cons.WriteTo(tr.Writer())

	tr.OnClose(func() {
		stream.RemoveConsumer(cons)
	})

View on GitHub (pinned to c245815e75)