AlexxIT/go2rtc · error

api.StreamNotFound

Error message

api.StreamNotFound

What it means

Once the stream name is parsed, apiStream looks it up via streams.Get(name); if no stream with that name exists it returns api.StreamNotFound with HTTP 404. This means go2rtc has no registered stream under that identifier.

Solutions

  1. Add the stream first via POST /stream/{name}/add or define it under streams: in go2rtc.yaml
  2. Verify the name matches exactly (case-sensitive) the stream name in go2rtc config
  3. List existing streams (GET /api/streams) to confirm the expected name exists
  4. If using dynamic add from HA, check the /add call succeeded before calling the webrtc endpoint

Example fix

// before
curl /api/stream/typo-name/channel/0/webrtc -> 404 stream not found
// after
curl -X POST -d '{"name":"cam1",...}' /api/stream/cam1/add
curl /api/stream/cam1/channel/0/webrtc -> 200
Defensive patterns

Strategy: validation

Validate before calling

const streams = await (await fetch('/api/streams')).json();
if (!streams.some(s => s.name === streamName)) {
  throw new Error(`stream "${streamName}" not registered in go2rtc`);
}

Try / catch

const res = await fetch(webrtcUrl, opts);
if (res.status === 404) {
  // api.StreamNotFound — register the stream via /add or go2rtc.yaml first
}

Prevention

When it happens

Trigger: GET/POST /stream/{name}/channel/0/webrtc where {name} was never added (no streams: entry in config, the /add call never ran, or the name is misspelled).

Common situations: Home Assistant integration referencing a camera whose stream was never registered; go2rtc restarted without persistent config so dynamic /add streams are gone; case-sensitive name mismatch; stream deleted while HA still references it.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at internal/hass/api.go:50

		// 3. dynamic link to Hass camera
		if _, err := streams.Patch(v.Name, v.Channels.First.Url); err == nil {
			apiOK(w, r)
		} else {
			http.Error(w, err.Error(), http.StatusBadRequest)
		}

	// /stream/{id}/channel/0/webrtc
	default:
		i := strings.IndexByte(r.RequestURI[8:], '/')
		if i <= 0 {
			http.Error(w, "", http.StatusBadRequest)
			return
		}

		name := r.RequestURI[8 : 8+i]
		stream := streams.Get(name)
		if stream == nil {
			http.Error(w, api.StreamNotFound, http.StatusNotFound)
			return
		}

		if err := r.ParseForm(); err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		s := r.FormValue("data")
		offer, err := base64.StdEncoding.DecodeString(s)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		s, err = webrtc.ExchangeSDP(stream, string(offer), "hass/webrtc", r.UserAgent())
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)

View on GitHub (pinned to c245815e75)