{"record":{"id":"e912448bed45c4c6","repo":"AlexxIT/go2rtc","slug":"onvif-wrong-subtype","errorCode":null,"errorMessage":"onvif: wrong subtype","messagePattern":"onvif: wrong subtype","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/onvif/client.go","lineNumber":62,"sourceCode":"\ts = FindTagValue(b, \"Imaging.+?XAddr\")\n\tclient.imaginURL = baseURL + GetPath(s, \"/onvif/imaging_service\")\n\n\treturn client, nil\n}\n\nfunc (c *Client) GetURI() (string, error) {\n\tquery := c.url.Query()\n\n\ttoken := query.Get(\"subtype\")\n\n\t// support empty\n\tif i := atoi(token); i >= 0 {\n\t\ttokens, err := c.GetProfilesTokens()\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tif i >= len(tokens) {\n\t\t\treturn \"\", errors.New(\"onvif: wrong subtype\")\n\t\t}\n\t\ttoken = tokens[i]\n\t}\n\n\tgetUri := c.GetStreamUri\n\tif query.Has(\"snapshot\") {\n\t\tgetUri = c.GetSnapshotUri\n\t}\n\n\tb, err := getUri(token)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\trawURL := FindTagValue(b, \"Uri\")\n\trawURL = strings.TrimSpace(html.UnescapeString(rawURL))\n\n\tu, err := url.Parse(rawURL)","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/onvif/client.go#L44-L80","documentation":"GetURI in pkg/onvif/client.go lets callers select an ONVIF media profile by numeric index (subtype). When the token in the URI is a non-negative integer, the client fetches GetProfilesTokens and treats the number as an index into that list; if the index is >= the number of profiles the device exposes, it returns errors.New(\"onvif: wrong subtype\").","triggerScenarios":"Calling GetURI with a stream subtype like 1, 2, 3 ... on a camera whose GetProfiles response contains fewer profiles — e.g. requesting subtype 1 on a single-profile camera, or a higher index on a camera with only 2 profiles.","commonSituations":"Reusing a URL template that worked on one camera model on another camera with fewer profiles; assuming 0-based vs 1-based indexing mismatches; firmware update that reduced the number of profiles; a camera whose media profiles only include one main stream.","solutions":["Use subtype 0 (or the lowest valid index) and confirm how many profiles the camera actually has via GetProfilesTokens","Enumerate the device's profiles with GetProfile/GetProfilesTokens and pick the profile token directly instead of a numeric subtype","Check 0-based vs 1-based indexing expectations against the library's implementation (i indexes into the tokens slice directly)","Update the camera firmware or add/reconfigure media profiles on the device if you genuinely need a second stream","Log len(tokens) at startup and fail fast with a clear message when the configured subtype exceeds it"],"exampleFix":"// before\nuri, err := cam.GetURI(\"onvif://...?subtype=1\") // camera has only 1 profile\n// after\ntokens, err := cam.GetProfilesTokens()\nif err != nil { return err }\nsub := 1\nif sub >= len(tokens) { sub = 0 } // fall back to the only profile\nuri, err = cam.GetURI(fmt.Sprintf(\"onvif://...?subtype=%d\", sub))","handlingStrategy":"validation","validationCode":"tokens, err := c.GetProfilesTokens()\nif err != nil { return err }\nif subtype >= len(tokens) {\n    return fmt.Errorf(\"subtype %d out of range: device has %d profile(s)\", subtype, len(tokens))\n}","typeGuard":"func validSubtype(subtype int, tokenCount int) bool {\n    return subtype >= 0 && subtype < tokenCount\n}","tryCatchPattern":"uri, err := cam.GetURI(u)\nif err != nil {\n    if err.Error() == \"onvif: wrong subtype\" {\n        return cam.GetURI(strings.Replace(u, \"subtype=1\", \"subtype=0\", 1))\n    }\n    return err\n}","preventionTips":["Discover profile count via GetProfilesTokens at startup and clamp the configured subtype","Don't copy stream subtypes between camera models — each device has its own profile table","Confirm 0-based indexing used by this library when mapping subtype numbers","Persist the actual profile token rather than the numeric subtype for long-lived configs"],"tags":["onvif","camera","profiles","validation"],"backgroundTag":"index-out-of-range","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"}