AlexxIT/go2rtc · error

api.StreamNotFound

Error message

api.StreamNotFound

What it means

The HLS-over-WebSocket handler looks up the stream named in the request query via streams.GetOrPatch. If no stream with that name exists (or the name is empty), it returns the shared api.StreamNotFound sentinel error, so the WS client knows the requested stream is unavailable.

Solutions

  1. Verify the stream name in the query matches a stream key in the config exactly
  2. List configured streams via GET /api/streams and correct the src parameter
  3. If the stream was removed, restore it in config and reload

Example fix

// before
new WebSocket('ws://host:1984/api/ws?src=cam_1')
// after
new WebSocket('ws://host:1984/api/ws?src=cam1')  // matches streams: cam1: ...
Defensive patterns

Strategy: validation

Validate before calling

const src = new URLSearchParams({src: 'cam1'})
const streams = await (await fetch('/api/streams')).json()
if (!(src.get('src') in streams)) throw new Error('stream not configured')

Try / catch

ws.onerror = async () => { const streams = await (await fetch('/api/streams')).json(); if (!(name in streams)) showAlert('stream not found') }

Prevention

When it happens

Trigger: Opening the HLS WebSocket endpoint (/api/ws?src=NAME) with a src that doesn't match any configured stream name; stream removed/reloaded between page load and WS connect; case/typo mismatch in src.

Common situations: Front-end built for a different stream name; config reloaded removing the stream; URL-encoding issues mangling the src parameter.

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/31767e7375e78fab. Report an issue: GitHub.

Appendix: source

Thrown at internal/hls/ws.go:16

package hls

import (
	"errors"
	"time"

	"github.com/AlexxIT/go2rtc/internal/api"
	"github.com/AlexxIT/go2rtc/internal/api/ws"
	"github.com/AlexxIT/go2rtc/internal/streams"
	"github.com/AlexxIT/go2rtc/pkg/mp4"
)

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

	codecs := msg.String()
	medias := mp4.ParseCodecs(codecs, true)
	cons := mp4.NewConsumer(medias)
	cons.FormatName = "hls/fmp4"
	cons.WithRequest(tr.Request)

	log.Trace().Msgf("[hls] new ws consumer codecs=%s", codecs)

	if err := stream.AddConsumer(cons); err != nil {
		log.Error().Err(err).Caller().Send()
		return err
	}

	session := NewSession(cons)

	session.alive = time.AfterFunc(keepalive, func() {

View on GitHub (pinned to c245815e75)