{"record":{"id":"7e0ae9066e812aa0","repo":"AlexxIT/go2rtc","slug":"onvif-unsupported-service","errorCode":null,"errorMessage":"onvif: unsupported service","messagePattern":"onvif: unsupported service","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/onvif/client.go","lineNumber":179,"sourceCode":"\tswitch operation {\n\tcase DeviceGetServices:\n\t\toperation = `<tds:GetServices><tds:IncludeCapability>true</tds:IncludeCapability></tds:GetServices>`\n\tcase DeviceGetCapabilities:\n\t\toperation = `<tds:GetCapabilities><tds:Category>All</tds:Category></tds:GetCapabilities>`\n\tdefault:\n\t\toperation = `<tds:` + operation + `/>`\n\t}\n\treturn c.Request(c.deviceURL, operation)\n}\n\nfunc (c *Client) MediaRequest(operation string) ([]byte, error) {\n\toperation = `<trt:` + operation + `/>`\n\treturn c.Request(c.mediaURL, operation)\n}\n\nfunc (c *Client) Request(url, body string) ([]byte, error) {\n\tif url == \"\" {\n\t\treturn nil, errors.New(\"onvif: unsupported service\")\n\t}\n\n\te := NewEnvelopeWithUser(c.url.User)\n\te.Append(body)\n\n\tclient := &http.Client{Timeout: time.Second * 5000}\n\tres, err := client.Post(url, `application/soap+xml;charset=utf-8`, bytes.NewReader(e.Bytes()))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer res.Body.Close()\n\n\tif res.StatusCode != http.StatusOK {\n\t\treturn nil, errors.New(\"onvif: wrong response \" + res.Status)\n\t}\n\n\treturn io.ReadAll(res.Body)\n}","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/onvif/client.go#L161-L197","documentation":"Request in pkg/onvif/client.go is the low-level SOAP dispatcher for all ONVIF service calls (GetProfile, GetVideoSourceConfiguration, GetStreamUri, GetSnapshotUri, GetServiceCapabilities, DeviceRequest). Each service method resolves a service URL (device/media/etc.); if the resolved URL is an empty string — meaning the device did not expose that service or the capability was never discovered — Request refuses to send and returns errors.New(\"onvif: unsupported service\").","triggerScenarios":"Calling any ONVIF operation when the corresponding service URL is empty: the camera does not implement the media service (no GetStreamUri/GetSnapshotUri/GetProfile), or the device/PTZ/etc. service was not found during capability discovery.","commonSituations":"Cheap/IP cameras that omit ONVIF media or analytics services entirely; a camera that reports services at discovery time but whose URLs weren't populated (device returned no XAddr for the service); calling snapshot/stream helpers against a doorbell or encoder that only implements device service.","solutions":["Check which services the camera exposes (DeviceService/GetServices or GetCapabilities) and only call operations for services that exist","Verify discovery populated the service URLs — re-probe the device and confirm mediaURL/deviceURL are non-empty before use","Use a camera/ONVIF-conformance tool (ONVIF Device Manager) to confirm whether the media service is implemented at all","Upgrade the camera firmware or choose a device with full ONVIF Profile S support if you need streaming URIs","Guard your code: call GetServiceCapabilities/GetStreamUri only when the corresponding URL field is non-empty"],"exampleFix":"// before\nuri, err := cam.GetStreamUri(...) // panics-free but errors: unsupported service\n// after\nif cam.GetStreamUriURL() == \"\" { // media service not exposed\n    return nil, errors.New(\"camera does not support ONVIF media service\")\n}\nuri, err := cam.GetStreamUri(...)","handlingStrategy":"type-guard","validationCode":"if c.mediaURL == \"\" {\n    return errors.New(\"device does not expose the ONVIF media service\")\n}","typeGuard":"func supportsMedia(c *onvif.Client) bool { return c.MediaURL() != \"\" }\nfunc supportsDevice(c *onvif.Client) bool { return c.DeviceURL() != \"\" }","tryCatchPattern":"uri, err := cam.GetStreamUri(ctx, tok)\nif err != nil {\n    if err.Error() == \"onvif: unsupported service\" {\n        return nil, fmt.Errorf(\"camera %s lacks ONVIF media service; streaming unavailable\", camID)\n    }\n    return err\n}","preventionTips":["Query GetServices/GetCapabilities before using stream/snapshot APIs and store which services exist","Prefer cameras with ONVIF Profile S conformance for streaming features","Re-run service discovery after firmware updates — URLs can appear/disappear","Centralize ONVIF calls behind a capability-checking wrapper so empty service URLs are handled in one place"],"tags":["onvif","soap","camera","unsupported-service"],"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"}