RTSP Digest Authentication Debugging

How to troubleshoot RTSP Digest authentication failures, 401 Unauthorized loops, stale nonce values, realm mismatches, Basic vs Digest camera settings, and URL credential problems.

rtsp digest authentication, 401 unauthorized, nonce, realm, basic vs digest, ip camera login, rtsp diagnostics

When an RTSP client answers a Digest challenge and receives another 401 Unauthorized, the protocol evidence is specific enough to test. Digest is not “the password, but encrypted.” It is a response computed from several exact strings. A mismatch in any input can look identical to a wrong secret at the player UI.

This guide isolates that calculation. For URL parsing, account permissions, protected stream paths, and method-by-method triage, begin with the broader RTSP authentication-loop guide.

Preserve the challenge and retry as one evidence unit

A simplified exchange looks like this:

C → S  DESCRIBE rtsp://camera.example/stream RTSP/1.0
       CSeq: 7

S → C  RTSP/1.0 401 Unauthorized
       CSeq: 7
       WWW-Authenticate: Digest realm="camera",
                         nonce="server-value",
                         qop="auth"

C → S  DESCRIBE rtsp://camera.example/stream RTSP/1.0
       CSeq: 8
       Authorization: Digest username="viewer", ...

Keep the request method and URI with both messages. A detached WWW-Authenticate header is insufficient because the method and digest URI are inputs to the response.

Reconstruct the calculation without logging the password

For the common MD5-based form, define:

HA1 = MD5(username : realm : password)
HA2 = MD5(method : digest-uri)

When no qop value is used:

response = MD5(HA1 : nonce : HA2)

With qop=auth, the response also includes nonce count and client nonce:

response = MD5(
  HA1 : nonce : nc : cnonce : qop : HA2
)

Colons above are literal separators. Case, whitespace, URI form, method, quoted-field parsing, and hexadecimal representation all matter. Use the algorithm and parameters actually advertised by the server; do not assume that every camera implements the same variant.

Recompute only in a controlled diagnostic environment. Do not place the password, HA1, or a reusable authorization value in public logs. A redacted report can still preserve field names, the advertised algorithm, realm, nonce-change behavior, qop, nc, method, URI shape, and final status.

Compare the realm byte for byte

The realm participates in HA1. A displayed label that “looks the same” may still differ because of capitalization, whitespace, encoding, or a challenge cached from another endpoint.

Check whether:

  • the retry copied the realm from the current challenge;
  • a proxy or recorder produced a different realm from the camera;
  • the client reused a challenge saved for another host or channel;
  • a firmware or configuration change invalidated cached authentication state;
  • multiple WWW-Authenticate challenges were offered and the client answered the intended one.

Do not normalize the realm for convenience. Hash the exact challenge value.

Treat the nonce as server-owned state

The nonce comes from the server and can expire or be replaced. If a new 401 includes stale=true and a fresh nonce, the server is indicating that the previous nonce is no longer acceptable; the client should form a new response using the new challenge.

Build a short nonce timeline:

Attempt Challenge nonce Retry nonce stale Result
1 fingerprint A fingerprint A absent 401 or success
2 fingerprint B fingerprint A or B true/absent 401 or success

Use fingerprints or redacted labels in a shared report. If the server issues nonce B while the client continues answering with nonce A, the cache boundary is visible. If the client uses B and still fails, move to the other inputs.

For qop=auth, verify that nc is formatted as the expected eight hexadecimal digits and advances appropriately for uses of the same nonce. Confirm that cnonce is present in both the calculation and header when required.

Compare three URI representations

Digest failures often hide in URI handling. Put these values side by side:

  1. The URI on the RTSP request line.
  2. The uri parameter inside Authorization.
  3. The URI string used to compute HA2.

They must follow the server’s expected form. Potential differences include absolute RTSP URI versus path, explicit versus implicit port, percent-encoding, query order, case-sensitive path components, or a proxy-rewritten target.

Do not “fix” the trace by normalizing all three before comparison. The difference itself is the evidence.

Bind the response to the actual RTSP method

HA2 includes the method. A response computed for DESCRIBE cannot simply be copied onto SETUP or PLAY. When the first protected method succeeds and a later one fails, confirm that the client recalculated authorization with the later method and current URI.

Use CSeq to associate every challenge with the correct request, especially when several track SETUP exchanges occur close together. Also retain the RTSP session identifier separately; it is session state, not a substitute for a correct Digest response.

Interpret repeated 401 patterns

  • No Authorization retry: scheme negotiation or credential configuration failed before Digest computation.
  • Same challenge and same bad response: stable input mismatch; compare method, realm, URI, user, and secret.
  • New nonce, old retry nonce: stale challenge cache.
  • Correct-looking fields but one client fails: compare raw request-line URI and parameter formatting between clients.
  • DESCRIBE succeeds, SETUP fails: recalculate for method and track URI; inspect per-method authorization policy.
  • Digest succeeds, later status is not 401: stop debugging the hash and move to resource, session, transport, SDP, RTP, or codec evidence.

Capture a safe regression case

Once the failure is understood, retain a sanitized fixture containing request methods, URI shapes, CSeq, challenge parameter structure, redacted authorization metadata, and expected status transitions. Never retain working plaintext credentials in the fixture.

RTSP Inspector records the RTSP control timeline and redacts authorization evidence in its diagnostic path. The valuable output is not “login failed”; it is a reproducible boundary such as “client reused the previous nonce,” “Digest URI differed from the request URI,” or “authorization was not recalculated for SETUP.”

Identify the authentication boundary before retrying

One 401 Unauthorized is not necessarily a failure. Many Digest servers intentionally send the first 401 as a challenge. The actionable boundary is the result of the authenticated retry: did the client choose the advertised scheme, reproduce the current challenge fields, and calculate the response for the exact method and URI? Record the first unauthenticated request separately from later retries.

Observation Bounded interpretation Next safe action
First DESCRIBE receives 401 with WWW-Authenticate: Digest Normal challenge is possible Check whether one authenticated retry follows
Retry omits Authorization Client/configuration did not enter Digest flow Inspect credentials source and scheme selection
Retry uses Basic while server offers Digest only Scheme mismatch Select a supported method; do not brute-force retries
Retry has current nonce but returns 401 One Digest input or server policy remains incompatible Compare realm, URI, method, qop, and account permissions
New challenge says stale=true Previous nonce expired Recalculate once with the new challenge
DESCRIBE works, SETUP gets 401 Path/method authorization changed later in the session Recompute for the track URL and SETUP method

The RTSP 401 versus 404 camera URL guide covers the resource/authentication distinction. Do not modify camera accounts or security policy merely because a client UI reduces the evidence to “wrong password.”

Check qop, algorithm, and header parsing explicitly

Many integrations implement a subset of Digest. A camera may offer qop=auth, omit qop, use an algorithm variant, quote fields differently, or advertise multiple challenges. A proxy can also change the authority/realm boundary. Preserve the header structure and compare it to the client capability rather than normalizing it away.

Challenge detail Why it changes the response Evidence to retain without secrets
realm It is part of HA1 Exact length/case/encoding marker or a private fingerprint
nonce Server-owned challenge state Redacted nonce fingerprint and chronological order
qop=auth Requires nc and cnonce in the common form Presence, formatting, and increment behavior
opaque May have to be echoed Whether it appears in retry, not its reusable value
algorithm field Selects the expected digest calculation Advertised token and client support result
multiple schemes Client must choose a compatible challenge Full scheme list and selected scheme

Do not log a complete Authorization header to solve a 401. It can contain response material tied to a password. A secure support fixture replaces secrets with fixed placeholders while retaining field order, quoted/unquoted structure, request method, URI shape, challenge type, and expected result.

Compare direct camera, NVR, and client boundaries

An NVR or proxy can terminate RTSP authentication itself, then open a distinct session upstream. If the direct camera and NVR return different realms or methods, that is not an inconsistency in the capture—it is evidence of two authentication authorities. Test only authorized endpoints and label the boundary in the case.

Comparison What it can reveal
Same account, direct camera vs NVR Whether the realm/challenge comes from a proxy boundary
Same URI, new client process Whether the client cached a stale nonce or realm
Same challenge, different RTSP method Whether HA2/method recalculation is missing
Encoded vs separately supplied credentials Whether URL parsing is corrupting identity input
Known-good account, same stream path Whether account permission is distinct from Digest formatting

Never treat a working web UI login as proof that RTSP Digest must work. HTTP and RTSP can use different services, accounts, schemes, stream permissions, and NVR routing. The most useful statement is exactly where the challenge/retry sequence diverges.

Digest authentication QA checklist

  1. Start a clean client session so cached challenge state is known.
  2. Capture the initial request, 401 challenge, and exactly one sanitized retry.
  3. Record CSeq, method, request-line URI, selected scheme, realm fingerprint, nonce fingerprint, qop/algorithm tokens, and status.
  4. If a new 401 is returned, check stale and compare the challenge to the previous one before issuing another request.
  5. Continue to SETUP only after DESCRIBE is understood; retain per-track URI and method.
  6. Stop retries when an account lockout or rate policy is possible; hand the evidence to the administrator.
QA case Acceptance evidence
Initial challenge Digest scheme and expected retry are captured without credentials
Nonce refresh Old/new challenge distinction and one fresh retry are visible
Track setup Authorization is recalculated for SETUP and track URI
Proxy boundary Direct/NVR realm and status are labelled separately
Regression fixture Redacted data can reproduce header parsing without secrets

Questions about RTSP Digest 401 errors

Does a repeated 401 always mean a wrong password?

No. The account may be wrong, but a realm, nonce, URI, method, qop, algorithm, permission, or proxy boundary mismatch can produce the same status. The challenge and retry must be read together.

Should the client reuse a Digest response for every RTSP method?

No. The method and URI participate in the calculation. A successful DESCRIBE response cannot simply be copied to a track SETUP request.

Can a stale nonce be fixed by retrying continuously?

No. Use the fresh challenge once with the correct inputs. Continuous retries can cause device lockouts and hide the original evidence.

What can RTSP Inspector prove?

It can retain the control sequence, challenge fields, request URI/method boundary, retry behavior, and status codes with secrets redacted. It cannot prove an undisclosed password, hidden account policy, or firmware-side authentication implementation without device-side evidence.

A good Digest diagnosis names the exact divergence—current nonce not used, URI mismatch, unsupported qop, later track policy, or unknown server-side authorization—not simply “RTSP login failed.”

How do you verify a Digest correction?

Begin a fresh connection so cached authorization state cannot hide the bug. Preserve the first 401 challenge, realm, nonce, algorithm, qop, method, request URI, nonce count, cnonce, and the next response status. Redact credentials and response hashes from shared artifacts while retaining the fields needed to compare request construction.

Run one control request with the vendor-supported client and the same sanitized URL shape. If DESCRIBE authenticates but SETUP for one track returns another 401, report the track URI and challenge change rather than calling the whole login invalid. A successful fix must survive a new nonce and reconnect. The authentication-loop guide and troubleshooting help keep the control sequence reviewable.

Retain the redacted fresh-connection challenge and successful retry as acceptance evidence. That proves the correction survives new authorization state rather than depending on a cached session that will fail again later.

<!-- multilingual-related-reading:start -->

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 -->