Correctif de requête incorrecte RTSP 400 : DÉCRIVEZ un échec, une URL de caméra mal formée et des erreurs d'en-tête

Correction de la mauvaise requête RTSP 400 sur DESCRIBE. Couvre les URL de caméra mal formées pour Axis/Dahua/Hikvision, les en-têtes non pris en charge, les problèmes de proxy inverse, l'authentification et les chemins de flux spécifiques au fournisseur avec de véritables commandes de diagnostic.


« RTSP/1.0 400 Bad Request » signifie que la caméra a rejeté votre demande RTSP comme étant mal formée. Ce n'est pas un problème de réseau. Ce n'est pas un problème de codec. Il s’agit d’un problème de format de demande – et il peut être résolu une fois que vous voyez la demande exacte reçue par la caméra.

Réponse rapide : triage en 30 secondes

  1. Testez d'abord avec VLC. Si VLC fonctionne, capturez la requête RTSP exacte qu'il envoie. Comparez avec votre client défaillant.
  2. Vérifiez le chemin de l'URL. Différentes caméras utilisent des chemins complètement différents pour le même flux RTSP. La copie d'une URL d'une marque d'appareil photo à une autre est la cause n°1 de 400 erreurs.
  3. Check URL encoding. Special characters in passwords break RTSP URL parsing. Encode @ as %40, : as %3A, / as %2F.
  4. Vérifiez les interférences du proxy. Le RTSP direct vers la caméra fonctionne mais via un proxy renvoie 400 ? Le proxy modifie les en-têtes RTSP.

Si aucune de ces solutions ne résout le problème, parcourez les sections détaillées ci-dessous.

Premièrement : vérifiez que la caméra est accessible

Avant de déboguer RTSP, confirmez la connectivité de base :

# TCP reachability
nc -zv 192.168.1.100 554

# Or with telnet
telnet 192.168.1.100 554

# RTSP OPTIONS — the simplest RTSP request
# If this fails, the camera isn't speaking RTSP

If the port is closed, the problem is network/firewall, not RTSP.

Camera-specific URL formats

The most common cause of 400 errors: using the wrong URL path format for your camera brand. Each manufacturer uses different conventions:

Axis

rtsp://<ip>/axis-media/media.amp
rtsp://<ip>/mpeg4/media.amp
rtsp://<ip>:554/axis-media/media.amp?videocodec=h264

Dahua

rtsp://<user>:<pass>@<ip>:554/cam/realmonitor?channel=1&subtype=0
rtsp://<user>:<pass>@<ip>:554/cam/realmonitor?channel=1&subtype=1
  • subtype=0: main stream
  • subtype=1: sub stream

Hikvision

rtsp://<user>:<pass>@<ip>:554/Streaming/Channels/101
rtsp://<user>:<pass>@<ip>:554/Streaming/Channels/102
  • 101: channel 1, main stream
  • 102: channel 1, sub stream
  • 201: channel 2, main stream

Generic / ONVIF

rtsp://<ip>:554/stream1
rtsp://<ip>:554/live
rtsp://<ip>:554/h264
rtsp://<ip>:554/h265
rtsp://<ip>:554/profile1/media.smp
rtsp://<ip>/onvif1
rtsp://<ip>/onvif2

Testing with ffmpeg

# Test DESCRIBE only (don't decode)
ffmpeg -rtsp_transport tcp -i "rtsp://user:pass@192.168.1.100:554/stream1" -t 1 -f null -

# La sortie détaillée montre l'échange RTSP exact
ffmpeg -loglevel debug -rtsp_transport tcp -i "rtsp://..." -t 1 -f null - 2>&1 | grep -E "DÉCRIRE|CONFIGURATION|réponse"

Encodage d'URL : le déclencheur silencieux 400

When a password contains special characters, the RTSP URL becomes ambiguous. The @ separates credentials from the host, so a password containing @ breaks the parsing.

WRONG: rtsp://admin:pa@ss@192.168.1.100/stream1
       parser sees: user=admin, pass=pa, host=ss@192.168.1.100

RIGHT:  rtsp://admin:pa%40ss@192.168.1.100/stream1
       parser sees: user=admin, pass=pa@ss, host=192.168.1.100

Characters that must be encoded in RTSP URLs:

Character Encoding Example
@ %40 user@domainuser%40domain
: %3A pass:wordpass%3Aword
/ %2F pass/wordpass%2Fword
? %3F in query values
# %23 in query values
% %25 literal percent
& %26 in query values (if not separating parameters)
space %20 in query values

Config files often add another layer of escaping. A URL in a YAML file may need both YAML escaping AND URL encoding.

Full diagnostic decision tree

RTSP returns 400 Bad Request
│
├─ Is port 554 reachable?
│  ├─ NO → Fix network/firewall. Not an RTSP issue.
│  └─ YES → Continue
│
├─ Does VLC play the same URL?
│  ├─ YES, VLC works → Capture VLC's exact request. Compare with your client.
│  │   Differences in headers, URI format, or auth will point to the fix.
│  └─ NO, VLC also fails → Problem is in the URL or camera config
│
├─ Check the URL path
│  ├─ Wrong manufacturer format → Use correct format for your camera brand
│  ├─ Query parameters missing → Add required parameters (channel, subtype)
│  └─ Path contains unencoded special chars → URL-encode credentials
│
├─ Check DESCRIBE headers
│  ├─ Missing Accept: application/sdp → Add it
│  ├─ Extra HTTP headers (via proxy) → Remove proxy from RTSP path
│  └─ Malformed Authorization → Fix Digest auth parameters
│
├─ Check CSeq and RTSP syntax
│  ├─ Missing CSeq → Add sequential CSeq header
│  ├─ Wrong RTSP version → Use RTSP/1.0
│  └─ CRLF formatting wrong → Ensure \r\n line endings
│
└─ Still failing?
   ├─ Try ONVIF discovery to get the correct RTSP URL
   ├─ Check camera firmware version (older firmware may have stricter parsing)
   └─ Test with a known-working RTSP client as baseline

Proxy inverse : la cause cachée des 400

RTSP via un proxy inverse HTTP est fragile. Les proxys conçus pour HTTP peuvent :

  1. Injecter des en-têtes spécifiques à HTTP (Host, X-Forwarded-For, User-Agent)
  2. Réécrire l'URI de la requête
  3. Tamponner et modifier le comportement de la connexion TCP
  4. Interférer avec le modèle de connexion persistante de RTSP

Symptômes d'interférence de proxy :

  • RTSP direct vers la caméra : fonctionne
  • RTSP via proxy : 400 requêtes incorrectes
  • Les journaux de caméra affichent une "demande mal formée" avec des en-têtes supplémentaires non présents dans le flux direct

Correction : Soit vous contournez le proxy pour le trafic RTSP, soit vous utilisez un proxy compatible RTSP, soit vous configurez le proxy pour transmettre le trafic RTSP sans modification.

Cas extrêmes d’authentification

La plupart des problèmes d'authentification renvoient 401, mais un en-tête Authorization mal formé peut renvoyer 400.

Le modèle « fonctionne au premier essai, échoue lors d'une nouvelle tentative » :

  1. Le client envoie une description non authentifiée.
  2. La caméra renvoie 401 avec le défi Digest (domaine, occasionnel)
  3. Le client calcule la réponse Digest
  4. Le client envoie DESCRIBE authentifié avec en-tête d'autorisation
  5. La caméra renvoie 400

Cela se produit lorsque le calcul de la réponse Digest est erroné : l'URI utilisé dans le calcul Digest ne correspond pas à l'URI réel de la requête, ou le nom occasionnel était périmé, ou les caractères spéciaux du mot de passe n'étaient pas codés correctement avant le hachage.

Vérifiez : Comparez l'URI de la demande dans l'en-tête Autorisation avec l'URI de la demande réel sur le câble. Dans l'authentification Digest, l'URI fait partie du hachage — s'ils ne correspondent pas caractère à caractère (y compris l'encodage), la réponse n'est pas valide.

Quand la caméra est juste cassée

Certaines caméras ont des implémentations RTSP boguées. Si vous avez tout vérifié ci-dessus et que vous obtenez toujours 400 :

  1. Rechercher les mises à jour du micrologiciel
  2. Test avec le logiciel client du fabricant
  3. Essayez ONVIF comme chemin alternatif de découverte et de streaming
  4. Si la caméra fonctionne avec sa propre application mais pas avec des clients RTSP conformes aux normes, la pile RTSP de la caméra n'est pas conforme

Signalez un bug auprès du fournisseur de l'appareil photo. Incluez la demande et la réponse RTSP DESCRIBE exactes. Une implémentation RTSP appropriée ne devrait pas renvoyer 400 pour une requête valide et bien formée, quel que soit le chemin de l'URL : elle devrait renvoyer 404.