{"record":{"id":"9bd384a2cb19c0a0","repo":"AlexxIT/go2rtc","slug":"unsupported-operation","errorCode":null,"errorMessage":"unsupported operation","messagePattern":"unsupported operation","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"internal/onvif/onvif.go","lineNumber":147,"sourceCode":"\tcase onvif.MediaGetVideoSourceConfiguration:\n\t\ttoken := onvif.FindTagValue(b, \"ConfigurationToken\")\n\t\tb = onvif.GetVideoSourceConfigurationResponse(token)\n\n\tcase onvif.MediaGetStreamUri:\n\t\thost, _, err := net.SplitHostPort(r.Host)\n\t\tif err != nil {\n\t\t\thost = r.Host // in case of Host without port\n\t\t}\n\n\t\turi := \"rtsp://\" + host + \":\" + rtsp.Port + \"/\" + onvif.FindTagValue(b, \"ProfileToken\")\n\t\tb = onvif.GetStreamUriResponse(uri)\n\n\tcase onvif.MediaGetSnapshotUri:\n\t\turi := \"http://\" + r.Host + \"/api/frame.jpeg?src=\" + onvif.FindTagValue(b, \"ProfileToken\")\n\t\tb = onvif.GetSnapshotUriResponse(uri)\n\n\tdefault:\n\t\thttp.Error(w, \"unsupported operation\", http.StatusBadRequest)\n\t\tlog.Warn().Msgf(\"[onvif] unsupported operation: %s\", operation)\n\t\tlog.Debug().Msgf(\"[onvif] unsupported request:\\n%s\", b)\n\t\treturn\n\t}\n\n\tlog.Trace().Msgf(\"[onvif] server response:\\n%s\", b)\n\n\tw.Header().Set(\"Content-Type\", \"application/soap+xml; charset=utf-8\")\n\tif _, err = w.Write(b); err != nil {\n\t\tlog.Error().Err(err).Caller().Send()\n\t}\n}\n\nfunc apiOnvif(w http.ResponseWriter, r *http.Request) {\n\tsrc := r.URL.Query().Get(\"src\")\n\n\tvar items []*api.Source\n","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/internal/onvif/onvif.go#L129-L165","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"null","handlingStrategy":"fallback","validationCode":"supportedOps := map[string]bool{\n    \"GetCapabilities\": true, \"GetServices\": true, \"GetDeviceInformation\": true,\n    \"GetVideoSources\": true, \"GetProfiles\": true, \"GetProfile\": true,\n    \"GetStreamUri\": true, \"GetSnapshotUri\": true, \"SystemReboot\": true,\n}\nif !supportedOps[op] { useRtspDirectly = true }","typeGuard":null,"tryCatchPattern":"if resp.StatusCode == http.StatusBadRequest {\n    b, _ := io.ReadAll(resp.Body)\n    if strings.Contains(string(b), \"unsupported operation\") {\n        // fall back to plain RTSP/HTTP streaming instead of ONVIF control\n        return buildRtspSource(camera)\n    }\n}","preventionTips":["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"],"tags":["onvif","http","compatibility"],"backgroundTag":"unsupported-operation","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}