RTSP SETUP 404: Fix Aggregate Control URLs
How to troubleshoot RTSP aggregate control URLs, SDP control:* attributes, track-level control paths, SETUP 404 errors, PLAY failures, and camera URL construction bugs.
A successful DESCRIBE followed by SETUP 404 often means the client resolved an SDP track control URI against the wrong base, not that the camera disappeared. Reconstruct the effective RTSP track URL from Content-Base/Content-Location, session-level a=control:*, and media-level control attributes, then compare it byte-for-byte with each request URI. The transcript can prove a relative-URL or aggregate-control mismatch; it cannot guarantee undocumented paths that the camera omitted from SDP.
RTSP Inspector is useful because this failure is not about whether the player can draw video. It is about whether the RTSP client interpreted the session-level and media-level control attributes correctly.
The common symptom
A typical trace looks like this:
DESCRIBE rtsp://camera/live
200 OK
SDP contains a=control:*
SDP video media contains a=control:trackID=1
SETUP rtsp://camera/trackID=1
404 Not Found
The camera did not necessarily reject RTSP. The client may have constructed SETUP with the wrong base URL.
Session-level and media-level control
SDP can contain control attributes at different levels:
a=control:*
m=video 0 RTP/AVP 96
a=control:trackID=1
m=audio 0 RTP/AVP 97
a=control:trackID=2
The session-level control may identify the aggregate resource used for PLAY and PAUSE. The media-level control identifies each RTP track used for SETUP.
If a client treats every control value as an absolute path, it can create invalid URLs.
Relative vs absolute control URLs
RTSP SDP control values may be:
- Absolute RTSP URLs.
- Relative paths.
- Track identifiers.
*aggregate control.- Vendor-specific paths.
Examples:
a=control:rtsp://192.168.1.10/live/trackID=1
a=control:trackID=1
a=control:streamid=0
a=control:video
a=control:*
The client must combine relative track control values with the correct base URL. A tiny difference such as /live/trackID=1 vs /trackID=1 can turn a working camera into a 404 Not Found.
DESCRIBE succeeds but SETUP fails
This is one of the strongest search patterns for this article. DESCRIBE proves the camera accepted the main URL and returned SDP. SETUP failure points to transport negotiation, track URL construction, unsupported media track, or camera firmware behavior.
Evidence to collect:
- Original DESCRIBE URL.
- Content-Base header if present.
- Content-Location header if present.
- Session-level
a=control. - Media-level
a=controlfor each track. - Exact SETUP URL.
- SETUP response status.
- Transport header used by SETUP.
Without the SETUP URL, the diagnosis is incomplete.
Content-Base and Content-Location
Some cameras include Content-Base or Content-Location headers in the DESCRIBE response. These headers can affect how relative SDP control paths should be resolved.
Failure patterns:
- Client ignores
Content-Base. - Client uses the original DESCRIBE URL when camera intended a different base.
- Camera returns a base URL with trailing slash differences.
- Proxy rewrites the RTSP URL but not SDP.
- Client normalizes away a path component needed by the camera.
These details are exactly why protocol evidence matters.
PLAY uses aggregate control
After SETUP succeeds for one or more tracks, PLAY may need to target the aggregate control URL instead of a single track URL. Some cameras accept either. Others are strict.
Search symptoms:
- "RTSP SETUP works but PLAY fails"
- "RTSP 460 Only Aggregate Operation Allowed"
- "RTSP PLAY 404"
- "RTSP track SETUP OK no video"
If PLAY targets the wrong URI, the RTP stream may never start even though SETUP returned 200 OK.
Multi-track audio and video
The bug is easier to see when both audio and video exist:
m=video ...
a=control:trackID=1
m=audio ...
a=control:trackID=2
The client must SETUP both tracks with their own control URLs, then PLAY the correct aggregate URL. If the client only sets up video but PLAY targets audio, or if it merges both tracks into one SETUP URL, the camera may return an error that looks unrelated.
ONVIF profile URL vs RTSP track URL
ONVIF can report stream URIs that differ from the final SDP track URLs. A stream URI from ONVIF may be valid for DESCRIBE but not directly valid for every SETUP request.
That creates the common support phrase: "ONVIF works but RTSP URL fails." The next diagnostic step is to inspect the SDP and derived SETUP URLs, not to keep generating new ONVIF URLs.
Debug checklist
Use this workflow:
- Capture DESCRIBE response.
- Save
Content-BaseandContent-Location. - Extract session-level
a=control. - Extract each media-level
a=control. - Build expected SETUP URL manually.
- Compare it with the client SETUP URL.
- Check whether SETUP fails with 404, 461, or 500.
- Confirm whether PLAY targets aggregate or track URL.
- Check multi-track audio/video behavior.
- Preserve the exact RTSP request lines for vendor support.
Final diagnosis
RTSP aggregate control bugs hide inside SDP interpretation. A camera can accept DESCRIBE and still reject SETUP or PLAY if the client builds the wrong track or aggregate control URL.
RTSP Inspector helps expose the SDP control attributes, Content-Base headers, SETUP URLs, and PLAY target so engineers can prove whether the issue is URL construction, camera strictness, proxy rewriting, or client-side SDP handling.
Build the URL decision from recorded evidence
Do not begin with a guessed replacement URL. Start with one captured DESCRIBE transaction and write down the URL exactly as it appeared on the wire, including its path and any non-default port. Then place the response headers and every a=control attribute next to the following SETUP request. This makes an RTSP aggregate control problem reviewable by another engineer instead of depending on a player log that says only “open failed.”
| Evidence in the trace | What it controls | What to compare | Useful conclusion |
|---|---|---|---|
Request URI for DESCRIBE |
Initial resource | Host, port, path, trailing slash | Establishes the client base candidate |
Content-Base or Content-Location |
Server-provided base | Which base the client actually used | Reveals a path-resolution difference |
Session-level a=control:* |
Aggregate operation target | URI used for PLAY or PAUSE |
Separates aggregate playback from setup |
Media-level a=control:trackID=... |
One media track | URI used in matching SETUP |
Identifies a wrongly joined track path |
Session and Transport response |
Accepted server state | The following PLAY request |
Shows whether URL resolution or later state failed |
This table is also a practical handoff format. A camera vendor can answer a concrete question such as “should trackID=1 resolve below /live/ or below /?” much faster than a generic report that the RTSP URL does not work.
Repeat the relative-control resolution check
Suppose the client sends DESCRIBE rtsp://camera.example:8554/live/profile1 and receives a Content-Base ending in /live/profile1/. A media section later says a=control:trackID=1. The important test is not whether trackID=1 looks familiar; it is whether the client sent the derived URI the camera indicated. Preserve both strings and compare the path components one by one.
- Keep the scheme, host, port, and path from the chosen base.
- Apply the relative control value without silently removing a final path segment.
- Preserve the difference between a resource-relative path and a server-root path.
- Compare the derived result with the actual
SETUPrequest line. - Repeat for audio and video rather than assuming the first successful track establishes the second one.
An absolute media control URI should be used as recorded, while a=control:* is not a literal URL to concatenate. It signals an aggregate control relationship. A client that turns * into a track request can create a misleading 404 even though its prior DESCRIBE was valid. A client that sends PLAY to one video track when the camera requires an aggregate resource can succeed through SETUP and stop at playback.
The evidence supports a bounded claim: the trace can show what the client requested and what the server rejected. It cannot prove an undocumented camera URL simply because another player happens to work.
Separate URL construction from transport failure
Status codes are not interchangeable. A 404 on SETUP is often worth investigating as a control-URI problem before changing UDP, TCP, or credentials. If the camera accepts the same URI but rejects the Transport header with 461, follow the dedicated RTSP 461 unsupported transport workflow instead. If the camera accepts SETUP but later loses Session state, compare the request history using the RTSP 454 Session Not Found guide.
DESCRIBE404 means the initial resource itself is not accepted; inspect credentials, path, profile selection, and proxy rewrite.SETUP404 after a successful DESCRIBE means the derived track control URL deserves first attention.PLAY404 after successful track setup points to the aggregate control target or a server-specific playback resource.461 Unsupported Transportpoints to negotiation, not a missing control path.454 Session Not Foundpoints to state carried after setup, not to a new SDP base by itself.
This ordering keeps troubleshooting falsifiable. A successful transport change does not prove a URL fix, and a new URL does not prove that a firewall was never involved.
Check proxies, NVRs, and rewritten paths
The aggregate-control bug often appears only after an NVR, reverse proxy, or relay is inserted. The client may describe rtsp://nvr.example/camera/7, while the upstream camera exposes /live/profile1. A proxy can rewrite the initial request and forward the SDP unchanged. The downstream client then resolves trackID=1 against the NVR-facing path even though the upstream server expects a different resource.
Capture both sides when possible: the client-facing request and the upstream request. If only one side is available, record the advertised base headers, SDP control values, and exact downstream target. The ONVIF works but RTSP URL fails article explains why a discovered stream URI is only the starting point; the SDP remains the source for track-level control decisions.
Also retain a trailing-slash change introduced by middleware. One removed slash can change relative URL resolution without changing the visible stream name. Keep the unmodified request URI, response headers, and SDP body as separate artifacts.
Retain a small, useful diagnostic case
A useful case does not need raw media payloads. Retain RTSP request and response headers, SDP text, timing, CSeq values, and the first response that diverges from expectation. Mark each derived URL as “captured from server,” “constructed by client,” or “assumed by operator.” That label prevents a later reader from confusing an inferred aggregate URL with a URL actually present in SDP.
For a multi-track stream, include a compact sequence such as DESCRIBE → SETUP video → SETUP audio → PLAY. If video setup succeeds and audio setup fails, state which media-level control attribute belongs to each request. This is much more actionable than a screenshot of a black player window.
RTSP aggregate control FAQ
Does a=control:* mean I should send SETUP to *?
No. * normally identifies aggregate control for session-level operations. The media-level control values identify individual track targets for SETUP. Preserve the server SDP and verify how the client maps each value before changing the request path.
Why does another player work while my client gets SETUP 404?
Different clients can choose a different base URL, preserve a trailing slash, select a different profile, or issue setup in another order. Compare RTSP transcripts if you can capture them. “Works in another player” is a lead, not evidence that one guessed URL is universally correct.
Can ONVIF provide the final track URLs?
ONVIF can provide a stream URI, but the SDP returned by DESCRIBE still defines the media control attributes relevant to that RTSP session. Treat the ONVIF URI as the resource to describe and use the captured SDP to evaluate track and aggregate control.
When should I change from UDP to TCP?
Change transport only after preserving URL evidence. A transport error has a different signature from a SETUP 404. If a TCP attempt changes the status to 461 or reaches successful setup, keep both transcripts; they show two separate variables rather than one magical fix.
What should an escalation include?
Include redacted RTSP request lines, Content-Base or Content-Location, complete SDP control attributes, exact derived SETUP and PLAY URIs, response status, and the point in the sequence where behavior changes. Do not include passwords or private camera addresses in a public report.
Related guides
Continue with the same-language pages below. They cover adjacent stages without changing the canonical owner of this topic:
<!-- multilingual-related-reading:end -->