AlexxIT/go2rtc · warning
unsupported operation
Error message
unsupported operation
What it means
go2rtc's built-in ONVIF server only implements a fixed whitelist of ONVIF Device/Media operations (the switch in onvifDeviceService). When the parsed SOAP action does not match any supported case, the default branch returns 400 "unsupported operation" and logs the operation name plus the raw request at warn/debug level. This is an intentional limitation of the emulated ONVIF device.
Solutions
- Check the warn log line 'unsupported operation: X' to see exactly which call was rejected
- Upgrade go2rtc — new releases regularly add supported ONVIF operations
- Configure the client to use only RTSP streaming / basic discovery features rather than full ONVIF control
- Implement or contribute the missing operation in internal/onvif/onvif.go's switch
- File/consult a go2rtc GitHub issue for the specific operation
Example fix
null
Defensive patterns
Strategy: fallback
Validate before calling
supportedOps := map[string]bool{
"GetCapabilities": true, "GetServices": true, "GetDeviceInformation": true,
"GetVideoSources": true, "GetProfiles": true, "GetProfile": true,
"GetStreamUri": true, "GetSnapshotUri": true, "SystemReboot": true,
}
if !supportedOps[op] { useRtspDirectly = true } Try / catch
if resp.StatusCode == http.StatusBadRequest {
b, _ := io.ReadAll(resp.Body)
if strings.Contains(string(b), "unsupported operation") {
// fall back to plain RTSP/HTTP streaming instead of ONVIF control
return buildRtspSource(camera)
}
} Prevention
- Restrict ONVIF client integration to streaming/discovery features go2rtc supports
- Pin client ONVIF feature toggles (PTZ, events) to disabled when using go2rtc as the device
- Keep go2rtc updated for newly supported operations
- Read the warn log to learn which operation triggered the rejection
When it happens
Trigger: An ONVIF client (e.g. Home Assistant, an NVR) sends an operation go2rtc has not implemented, such as PTZ commands, GetVideoEncoderConfiguration for advanced setup, events, or firmware operations.
Common situations: Home Assistant or an NVR probing advanced ONVIF features; newer ONVIF Profile operations not in go2rtc's whitelist; third-party ONVIF tools testing full device compatibility against the emulator.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- onvif: wrong response
- err.Error()
- ffmpeg: unsupported version:
- res.Status
- milesone: authentication failed:
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/9bd384a2cb19c0a0.
Report an issue: GitHub.
Appendix: source
Thrown at internal/onvif/onvif.go:147
case onvif.MediaGetVideoSourceConfiguration:
token := onvif.FindTagValue(b, "ConfigurationToken")
b = onvif.GetVideoSourceConfigurationResponse(token)
case onvif.MediaGetStreamUri:
host, _, err := net.SplitHostPort(r.Host)
if err != nil {
host = r.Host // in case of Host without port
}
uri := "rtsp://" + host + ":" + rtsp.Port + "/" + onvif.FindTagValue(b, "ProfileToken")
b = onvif.GetStreamUriResponse(uri)
case onvif.MediaGetSnapshotUri:
uri := "http://" + r.Host + "/api/frame.jpeg?src=" + onvif.FindTagValue(b, "ProfileToken")
b = onvif.GetSnapshotUriResponse(uri)
default:
http.Error(w, "unsupported operation", http.StatusBadRequest)
log.Warn().Msgf("[onvif] unsupported operation: %s", operation)
log.Debug().Msgf("[onvif] unsupported request:\n%s", b)
return
}
log.Trace().Msgf("[onvif] server response:\n%s", b)
w.Header().Set("Content-Type", "application/soap+xml; charset=utf-8")
if _, err = w.Write(b); err != nil {
log.Error().Err(err).Caller().Send()
}
}
func apiOnvif(w http.ResponseWriter, r *http.Request) {
src := r.URL.Query().Get("src")
var items []*api.Source
View on GitHub (pinned to c245815e75)