AlexxIT/go2rtc · error
exec: rtsp module disabled
Error message
exec: rtsp module disabled
What it means
exec stream sources support two modes: piping raw data through a command, or rewriting a URL containing {output} into a local RTSP URL served by the built-in rtsp module. This error means the URL contained {output} (RTSP mode requested) but the rtsp module is not enabled/has no listening port, so exec cannot serve the stream.
Solutions
- Enable the RTSP module in config, e.g. api/rtsp: rtsp: listen: ":8554" so rtsp.Port is set
- Remove {output} from the exec URL and switch to pipe mode if RTSP serving is not wanted
- Verify the rtsp module actually initialized (check logs) and a port was bound
Example fix
// before
streams:
cam: exec:ffmpeg -i ... {output}
// after
rtsp:
listen: ":8554"
streams:
cam: exec:ffmpeg -i ... {output} Defensive patterns
Strategy: validation
Validate before calling
if strings.Contains(rawURL, "{output}") && rtsp.Port == "" { return errors.New("enable rtsp listen or drop {output} from exec URL") } Try / catch
if err := tryOpen(url); err != nil && strings.Contains(err.Error(), "rtsp module disabled") { config.Enable("rtsp.listen"); reload() } Prevention
- Whenever an exec URL contains {output}, ensure the rtsp section with listen is in the config
- Prefer pipe mode (no {output}) if you don't need RTSP
- Smoke-test configs after migration to confirm rtsp still enabled
When it happens
Trigger: A stream source like exec:...{output}... while the rtsp section is absent from the config (rtsp.Port is empty), e.g. rtsp module disabled or listen address not configured.
Common situations: Config has an exec: source with {output} but no [rtsp] section; rtsp listen was disabled intentionally; config migration dropped the rtsp listen option.
Related errors
- config file disabled
- echo: bin not in allow_paths:
- exec: bin not in allow_paths:
- exec: timeout
- expr: result is empty
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/497c1cb17e474db0.
Report an issue: GitHub.
Appendix: source
Thrown at internal/exec/exec.go:76
streams.HandleFunc("exec", execHandle)
streams.MarkInsecure("exec")
log = app.GetLogger("exec")
}
var allowPaths []string
func execHandle(rawURL string) (prod core.Producer, err error) {
rawURL, rawQuery, _ := strings.Cut(rawURL, "#")
query := streams.ParseQuery(rawQuery)
var path string
// RTSP flow should have `{output}` inside URL
// pipe flow may have `#{params}` inside URL
if i := strings.Index(rawURL, "{output}"); i > 0 {
if rtsp.Port == "" {
return nil, errors.New("exec: rtsp module disabled")
}
sum := md5.Sum([]byte(rawURL))
path = "/" + hex.EncodeToString(sum[:])
rawURL = rawURL[:i] + "rtsp://127.0.0.1:" + rtsp.Port + path + rawURL[i+8:]
}
cmd := shell.NewCommand(rawURL[5:]) // remove `exec:`
cmd.Stderr = &logWriter{
buf: make([]byte, 512),
debug: log.Debug().Enabled(),
}
if allowPaths != nil && !slices.Contains(allowPaths, cmd.Args[0]) {
_ = cmd.Close()
return nil, errors.New("exec: bin not in allow_paths: " + cmd.Args[0])
}
View on GitHub (pinned to c245815e75)