ORBNET Blog

RTSP Works in VLC but Not XProtect? Troubleshooting Guide

Written by Justin Butterworth | 19 Aug 2026, 05:08:28

Why RTSP Works in VLC but Fails in XProtect

You have an RTSP URL.

You paste it into VLC.

Video appears immediately.

You add what appears to be exactly the same source to Milestone XProtect.

Nothing.

Black screen. Connection error. Perhaps it connects for a minute and then disappears.

So, if VLC can play it, why can't XProtect?

The useful answer is that VLC working proves the source can deliver playable media to VLC.

It doesn't prove that another RTSP client will negotiate that stream in exactly the same way.

That gives us a much better troubleshooting question:

Where is the first point that the successful VLC conversation and the unsuccessful XProtect conversation become different?

Once you start looking at the problem that way, RTSP troubleshooting becomes considerably less mysterious.

And considerably less dependent on changing random checkboxes until something happens.

Start in the right place

This is the first thing I would check, and it is surprisingly easy to miss.

If you tested the RTSP stream from your laptop, you haven't necessarily tested the same network path that XProtect is using.

The XProtect Recording Server is the component retrieving the video.

So wherever practical:

Take the exact RTSP URL and test it from the XProtect Recording Server.

Not something similar.

Not a URL with the query string removed because it looks neater.

The exact URL.

For example:

rtsp://192.168.10.20:554/channel1/stream1?profile=main

If VLC is available on the Recording Server, use it.

If it isn't, use another machine in the same network position or use ffprobe, which we'll come to shortly.

Why does this matter?

Because your laptop and the Recording Server may have completely different:

  • routing
  • VLAN access
  • firewall policies
  • DNS resolution
  • NAT behaviour
  • network security controls

A stream working from your engineering laptop only proves that the stream works from your engineering laptop.

That distinction has consumed more troubleshooting time over the years than I care to think about.

If the stream doesn't work from the Recording Server network position, stop there.

You have already learnt something useful.

This is probably not the time to investigate H.264 packetisation or an obscure Milestone setting.

Start with connectivity.

If it does work from the Recording Server, leave it running for a while.

One frame isn't enough.

We want:

Stable video.

Not:

"I saw a picture once, therefore this is definitely fine."

Ask the device what it thinks the stream is

If the source supports ONVIF, my next stop is normally ONVIF Device Manager, usually shortened to ODM.

A quick clarification here because this sometimes gets muddled:

ONVIF and RTSP aren't the same thing.

And for troubleshooting purposes, that is useful.

I tend to think of the tools like this:

VLC tells me whether I can consume the media.
ONVIF tells me how the device describes its media.
XProtect tells me whether that source can be consumed reliably as part of the VMS.

Open the device in ODM and look at the media configuration.

You are interested in:

  • available profiles
  • codec
  • resolution
  • frame rate
  • stream URI
  • whether the URI returned by the device is actually the same one you were given

That last one is particularly useful.

You may have been given:

rtsp://192.168.10.20/live

while the device itself reports something more like:

rtsp://192.168.10.20:554/channel1/stream1?profile=main

If that happens, test the device-advertised URI.

You have just replaced a guessed configuration with information coming from the device itself.

That is normally progress.

What if ODM doesn't discover the device?

That doesn't automatically mean RTSP is broken.

ONVIF discovery and direct RTSP playback are separate things.

You might have:

  • ONVIF disabled
  • discovery traffic blocked
  • different ONVIF credentials
  • multicast restrictions
  • partial or questionable ONVIF implementation

Treat ODM as another diagnostic view, not as a certification oracle.

If RTSP works directly but ODM doesn't, record that fact and continue.

Test TCP and UDP deliberately

This is where I would introduce FFmpeg / ffprobe.

VLC is excellent at answering:

Can I play this stream?

But VLC is deliberately good at making things work.

That is useful when watching video.

It is slightly less useful when you're trying to understand how the video was made to work.

ffprobe gives us a simple way of testing particular RTSP transport methods deliberately.

First, test RTSP over TCP:

ffprobe -hide_banner -rtsp_transport tcp "rtsp://192.168.10.20:554/channel1/stream1?profile=main"

Then test the exact same source using UDP:

ffprobe -hide_banner -rtsp_transport udp "rtsp://192.168.10.20:554/channel1/stream1?profile=main"

FFmpeg documents these RTSP transport options in its protocol documentation.

You aren't looking for a pretty video window here.

You are looking for whether ffprobe can establish the source and identify the media.

You might see output containing something broadly like:

Stream #0:0: Video: h264, 1920x1080, 25 fps

Now the result starts telling us where to look next.

TCP works and UDP works

Excellent.

We have evidence that both transport methods can work from this network position.

Move on.

TCP works but UDP fails

Also useful.

You probably don't have some mysterious generic "Milestone codec problem".

You have narrowed the problem towards things such as:

  • RTP delivery
  • UDP firewall rules
  • NAT
  • return routing
  • UDP transport negotiation

And when we configure XProtect, we already know which transport worked.

UDP works but TCP fails

Less common in many installations, but equally informative.

Again, the problem isn't:

"RTSP doesn't work."

The problem is now:

"One particular RTSP transport method doesn't work."

Much better.

Neither works

Go back to fundamentals.

Check:

  • IP connectivity
  • RTSP port
  • credentials
  • exact URI
  • whether the source is actually listening
  • whether VLC still works from the same machine

Don't keep adding complexity until you have a genuinely known-good source.

Use the simplest XProtect route first

Before we start changing Universal Driver settings, check whether you actually need the Universal Driver.

My order would normally be:

  1. Native Milestone/device-specific driver
  2. ONVIF driver where appropriate
  3. Milestone Universal Driver for a generic RTSP source

If the manufacturer's native driver works correctly:

Use it.

If ONVIF gives you the integration you require:

Use it.

If the Universal Driver works reliably:

Use it.

There isn't an engineering prize for making the architecture more complicated than it needs to be.

This point becomes quite important later when I start talking about ORBNET products.

If the built-in solution works, I'm not going to suggest inserting another piece of software purely because we happen to make one.

The specialist tools become relevant when the source or the workflow genuinely needs something different.

Configure the Universal Driver from facts, not guesses

The Universal Driver is extremely useful for generic RTSP sources.

But there are a handful of settings I would pay particular attention to.

Let's keep using the same source throughout:

rtsp://192.168.10.20:554/channel1/stream1?profile=main

Connection URI

This is one of the easiest places to go wrong.

Your complete RTSP URL is:

rtsp://192.168.10.20:554/channel1/stream1?profile=main

But the Universal Driver Connection URI is the path portion:

channel1/stream1?profile=main

Not the whole:

rtsp://192.168.10.20:554/channel1/stream1?profile=main

The host and RTSP port are configured independently.

It is obvious after somebody tells you.

It is considerably less obvious when you're staring at a black screen at 16:45 on a commissioning day.

RTSP Port

RTSP commonly uses:

554

But don't assume that it does.

If your known-good URL is:

rtsp://192.168.10.20:8554/channel1/stream1

then the RTSP port is:

8554

Use the source's actual configuration.

Codec

This is where the earlier tests start paying for themselves.

ODM or ffprobe should already have told you what the source is advertising.

If it is H.264, configure H.264.

If it is H.265, configure H.265.

Again:

Facts, not guesses.

Streaming Mode

The same principle applies here.

If your earlier test established:

TCP works. UDP fails.

then I would test the corresponding TCP streaming mode first.

You can come back to why UDP isn't working later if the application requires it.

First establish whether XProtect can successfully consume the known-good path.

Keep Alive type

This becomes particularly interesting when a stream:

  • connects normally
  • works for a predictable length of time
  • then disappears

If it dies after approximately 30, 60 or 120 seconds every time, I start thinking about session management rather than initial connectivity.

Depending on the source, different keep-alive behaviours such as OPTIONS, GET_PARAMETER or RTCP may matter.

Again, the symptom has given us somewhere sensible to look.

Include URI options on PLAY

This setting deserves a flashing arrow.

Remember our example?

rtsp://192.168.10.20:554/channel1/stream1?profile=main

Everything after the ? may be meaningful to the source.

It might identify:

  • a stream profile
  • a channel
  • an encoder
  • a token
  • some other device-specific option

Milestone's current Universal Driver documentation includes an Include URI options on PLAY setting.

If those query parameters are removed when the PLAY request is sent, the source can behave differently from the working VLC request.

You can therefore end up with the wonderfully confusing situation where much of the RTSP session looks fine, but the actual playback request isn't quite the same request VLC made.

If your URI contains:

?something=value

check this setting.

It is exactly the kind of tiny behavioural difference that makes:

"It works in VLC."

considerably less conclusive than it first appears.

Adding the hardware isn't the finish line

One other trap.

Successfully adding Universal Driver hardware does not mean you have proven stable video.

After adding it:

  • open live video
  • leave it running
  • confirm recording
  • reconnect
  • test it again
  • check it remains stable over time

The green tick isn't the end of the investigation.

The video is.

Authentication, and the clock behind it

Authentication deserves its own section, because it produces some of the most convincing false leads in RTSP troubleshooting.

A stream that authenticates happily in VLC can still fail in XProtect.

Start with the obvious things:

  • is the account you gave XProtect the same account you tested with?
  • does the source distinguish between an ONVIF user and an RTSP or media user?
  • does the account have permission to view the specific profile or channel?
  • has the device locked the account after repeated failed attempts?
  • does the source support Basic, Digest, or both?

Credentials embedded in a URL are worth a particular look.

If you tested with something like:

rtsp://admin:P%40ssw0rd@192.168.10.20:554/channel1/stream1?profile=main

then VLC handled the URL-encoded characters for you.

In XProtect, the credentials belong in the user name and password fields, not in the URI.

Characters such as @, :, / and ? in a password are a common source of an authentication failure that looks like a stream failure.

In a capture, the symptom is usually unmistakable:

DESCRIBE                  → 401 Unauthorized
DESCRIBE + Authorization   → 401 Unauthorized

A single 401 is normal. That is simply the device issuing a challenge.

A second 401 after the client has answered the challenge is the interesting one.

Fix authentication before you investigate anything else. You do not have an RTP problem yet.

Check the time, the date and the time zone

This is the part that gets skipped, and it belongs firmly in the authentication conversation.

Check the clock on both ends:

  • the video source or camera
  • the XProtect Recording Server

And check three things, not one:

  • time — are they within a few seconds of each other?
  • date — a device that has lost its clock often comes back on a default date years out
  • time zone and DST — the same instant expressed in the wrong zone is still the wrong timestamp

Why it matters here:

  • ONVIF security relies on timestamps, so a skewed clock can fail authentication while the credentials are perfectly correct
  • token-based or signed URLs expire, and a device with the wrong date may consider a valid token expired or not yet valid
  • RTSPS and any TLS-protected transport validate certificate dates, and a wrong clock puts the certificate outside its validity window
  • recorded video, alarms and exported evidence are only as trustworthy as the timestamps attached to them

So while you are there:

Point the source and the Recording Server at the same NTP source, set the time zone deliberately, and confirm the date.

It takes a minute.

It removes an entire category of authentication failure that otherwise looks like a broken stream.

Let the symptom tell you where to look

Before opening Wireshark, take a moment to describe the failure accurately.

Different symptoms point towards very different areas.

It doesn't connect at all

Start with:

  • reachability
  • credentials
  • RTSP port
  • URI
  • initial negotiation

DESCRIBE fails

Don't start debugging RTP.

You don't have an RTP problem yet.

The RTSP conversation hasn't got that far.

TCP works but UDP doesn't

Start thinking:

  • RTP delivery
  • firewall rules
  • NAT
  • return path
  • transport negotiation

The stream works, then drops after a predictable interval

Think:

  • session timeout
  • keep-alive behaviour
  • RTSP session maintenance

DESCRIBE, SETUP and PLAY all succeed but there is no video

Now check whether media actually arrives.

A successful RTSP PLAY response doesn't magically escort your RTP packets through the firewall afterwards.

These are different stages of the conversation.

And that brings us to the tool people often avoid until things get really unpleasant.

When the settings look right, stop guessing

Open Wireshark.

And before anybody disappears at the mention of packet captures, you do not need to understand every packet in the trace.

We're looking for a fairly simple sequence:

DESCRIBE → SETUP → PLAY → RTP

That is enough to make a surprising amount of progress.

Milestone's own Universal Driver testing guidance points you towards checking the DESCRIBE, SETUP and PLAY requests.

My approach would be:

  1. Capture VLC or ffprobe working.
  2. Capture XProtect failing.
  3. Preferably do both from the same machine or network position.
  4. Compare them.
  5. Find the first meaningful difference.

That is the whole game.

DESCRIBE

This is broadly the client asking:

"Tell me what media you have available."

The response usually contains SDP, or Session Description Protocol.

You don't need to decode every line.

Initially, look for things such as:

  • advertised codec
  • media track
  • control URI
  • anything obviously different between the successful and unsuccessful tests

For example:

m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000
a=control:trackID=1

For our purposes:

H264

tells us what codec the source advertised.

And:

trackID=1

identifies a media control target that may appear again during SETUP.

That's enough for now.

SETUP

The client is now effectively saying:

"This is how I would like you to deliver that media."

This is where TCP versus UDP differences can suddenly become very obvious.

Compare VLC and XProtect.

Did they request the same transport?

Did one ask for UDP client ports while the other requested TCP interleaving?

Did the device accept one and reject the other?

If so, you have found something considerably more useful than:

"XProtect doesn't seem to like it."

PLAY

Now the client is asking the source to start delivering media.

Check:

  • did PLAY succeed?
  • was the URI the same?
  • were the query parameters still present?
  • was the expected RTSP session used?

This is particularly relevant to the Include URI options on PLAY setting we looked at earlier.

RTP

And then the important bit.

Did the media actually arrive?

If:

DESCRIBE → 200 OK
SETUP    → 200 OK
PLAY     → 200 OK

but there is no media afterwards, then your RTSP control conversation may have succeeded.

The fault is now in a different category.

That is useful.

Useful Wireshark filters

Before the filters themselves, one distinction that saves a lot of pain.

Capture filter or display filter?

They are not the same thing, and they don't use the same syntax.

A capture filter decides what Wireshark writes to disk.
A display filter decides what you are shown from what was already captured.

Two practical consequences:

  • anything excluded by a capture filter is gone — you cannot get it back later by changing the display filter
  • a display filter is non-destructive, so you can change your mind as often as you like

Capture filters use BPF syntax, the same style used by tcpdump:

host 192.168.10.20

Display filters use Wireshark's own syntax:

ip.addr == 192.168.10.20

Putting rtsp into the capture filter box will simply be rejected. It isn't valid BPF.

My habit for this kind of work:

  • use a capture filter to keep the file manageable on a busy network, normally by host
  • use display filters to explore what you captured
  • keep the capture filter generous — never so tight that you lose the RTP you are trying to prove arrived

That last point matters. If you capture only port 554, you capture the RTSP conversation and none of the media.

Useful capture filters

Everything to and from the source, control traffic and media together. This is the one I use most:

host 192.168.10.20

The same source on a non-standard RTSP port, keeping UDP media as well:

host 192.168.10.20 and (tcp port 8554 or udp)

RTSP control traffic only, when you are chasing a negotiation problem:

tcp port 554

Two specific hosts, which is useful for source to Recording Server:

host 192.168.10.20 and host 192.168.10.50

Exclude your own remote-desktop session so the capture isn't drowned by it:

host 192.168.10.20 and not tcp port 3389

A UDP media port range, where the source uses a known range:

host 192.168.10.20 and udp portrange 30000-40000

If you are capturing on the Recording Server itself and it has more than one interface, choose the interface facing the source before worrying about filters at all.

Useful display filters

Start simple:

rtsp

Then:

rtsp || rtp || rtcp

If you only want traffic involving your source:

ip.addr == 192.168.10.20 && (rtsp || rtp || rtcp)

To concentrate on the main RTSP requests:

rtsp.method == "DESCRIBE" ||
rtsp.method == "SETUP" ||
rtsp.method == "PLAY"

And to look for RTSP errors:

rtsp.status >= 400

One small warning with RTP over UDP:

Wireshark may initially show the media simply as UDP because it hasn't identified the traffic as RTP.

If that happens, use Analyze → Decode As where appropriate and inspect the RTP stream.

Again, we are not trying to turn a security integrator into a protocol developer.

We're asking one much simpler question:

Does the stream XProtect is being offered look like the stream VLC was offered?

And if not:

Where did they become different?

What if the stream isn't actually broken?

This is where third-party video integration gets more interesting.

Historically, most XProtect video sources looked roughly like:

IP camera → XProtect

Today the "camera" might actually be:

  • a drone
  • a body-worn platform
  • a vehicle
  • a mobile device
  • a command-and-control platform
  • a specialist encoder
  • an analytics platform
  • a temporary deployment
  • another video system
  • something else entirely

Some of those systems produce excellent conventional RTSP.

Some produce RTSP that is slightly... creative.

And some don't use RTSP at all.

At some point the troubleshooting question needs to change from:

"How can I force this through the Universal Driver?"

to:

"What is actually the sensible way of getting this video into XProtect?"

That is where ORB Driver becomes relevant.

ORB Driver: when the source doesn't really behave like a camera

ORB Driver provides a more flexible XProtect-facing integration route for external video sources.

The important part isn't just the protocol list.

The important concept is:

ORB Driver's job is to make an unusual video source behave like something XProtect can sensibly manage.

Current supported workflows cover a broad range of external stream types, including:

  • RTSP / RTSPS
  • RTMP / RTMPS
  • SRT
  • RTP
  • WebRTC
  • HLS
  • MPEG-TS
  • MPEG-DASH
  • MJPEG

It can also provide transcoding where compatibility requires it.

That changes the integration discussion.

Instead of spending another hour trying to convince a drone, mobile platform or specialist video system that it is secretly an IP camera, you have a layer designed specifically to present those kinds of sources into XProtect.

But there is another category of problem that is worth separating from this one.

What if XProtect ingest isn't actually the problem?

Imagine the source is remote.

Perhaps it sits on:

  • 4G
  • 5G
  • another WAN
  • a temporary site
  • a vehicle
  • a drone
  • an unreliable connection
  • another organisation's network

Perhaps the source gives you SRT, but you need RTSP locally.

Perhaps several consumers need the same video.

Perhaps the source only allows a small number of connections.

Perhaps you need to:

  • convert protocols
  • normalise the source
  • route it
  • redistribute it
  • fan it out
  • deliver it to several systems

At that point:

This has stopped being an RTSP driver problem.
It is now a video transport problem.

That is where ORBNET Streaming Engine fits.

Streaming Engine: get the video from where it is to where it needs to be

I tend to describe Streaming Engine as:

Ingest → Convert → Route → Redistribute

It isn't simply another XProtect device driver.

It sits in the video path.

That means it can be useful where the real challenge is getting video:

from where and how it exists

to:

where and how it needs to exist.

Typical examples include:

  • SRT contribution over variable networks
  • converting between supported streaming protocols
  • receiving an external source and publishing RTSP locally
  • redistributing one source to multiple consumers
  • separating the source connection from the consuming systems
  • moving video between locations
  • routing streams under API control
  • delivering XProtect video to external systems, browsers or other consumers

And that distinction is important.

ORB Driver is primarily about presenting an unusual or supported external source into XProtect.

Streaming Engine is primarily about moving, converting, routing and distributing video.

They can be used independently.

Or they can be used together.

And that is where StreamForce fits

Once ORB Driver and Streaming Engine make sense individually, the wider StreamForce ecosystem becomes much easier to understand.

A complete workflow might look something like:

Source
  ↓
StreamLink, if required
  ↓
Streaming Engine, if required
  ↓
ORB Driver, if required
  ↓
XProtect

StreamLink is the edge contribution part of that architecture.

For example, it can sit at a remote or temporary location, acquire compatible local video and contribute it back using SRT.

That is useful for things such as:

  • remote sites
  • temporary deployments
  • vehicles
  • cellular connections
  • distributed camera networks
  • mobile or edge video sources

But the most important words in that architecture remain:

If required.

You don't need every component in every installation.

If XProtect's native driver works:

Use it.

If ONVIF works:

Use it.

If Universal Driver works:

Use it.

If an external source needs a more flexible XProtect-facing integration layer:

ORB Driver.

If the bigger problem is transport, conversion or distribution:

Streaming Engine.

If video also needs collecting at the edge and contributing back across a less predictable network:

StreamLink may become part of the architecture.

Use the layers the workflow actually needs.

No more.

There comes a point where changing another random RTSP checkbox isn't troubleshooting.

It's archaeology.

My troubleshooting order

If I arrived on site tomorrow and somebody said:

"The RTSP stream works in VLC but not XProtect."

this is the order I would work through it.

1. Get the exact RTSP URI

Include:

  • port
  • path
  • query parameters

Don't simplify it.

2. Test from the Recording Server network position

Use VLC or ffprobe.

If it fails here but succeeds from your laptop, investigate the network before XProtect.

3. Leave the stream running

Prove stability.

One frame doesn't count.

4. Check ONVIF if the source supports it

Use ODM to inspect:

  • media profile
  • codec
  • resolution
  • stream URI

Compare the URI reported by the source with the one you have been given.

5. Test TCP explicitly

ffprobe -hide_banner -rtsp_transport tcp "rtsp://192.168.10.20:554/channel1/stream1?profile=main"

6. Test UDP explicitly

ffprobe -hide_banner -rtsp_transport udp "rtsp://192.168.10.20:554/channel1/stream1?profile=main"

Record whether one works and the other doesn't.

7. Try the simplest appropriate Milestone integration

My order:

  1. Native/device-specific driver
  2. ONVIF where appropriate
  3. Universal Driver

If it works reliably, stop.

8. Check the Universal Driver Connection URI

For:

rtsp://192.168.10.20:554/channel1/stream1?profile=main

the Connection URI would be:

channel1/stream1?profile=main

9. Check the RTSP port

Don't assume 554.

Use the known-good source configuration.

10. Check the codec

Use the codec established by ODM, VLC or ffprobe.

11. Match the transport to your earlier testing

If TCP worked and UDP didn't, that matters.

12. Check Include URI options on PLAY

Particularly if your stream URI contains:

?

13. Check keep-alive behaviour

Especially if the stream disconnects after a predictable interval.

14. Capture the successful and failing sessions

Capture VLC or ffprobe working.

Then capture XProtect failing.

15. Compare

DESCRIBE → SETUP → PLAY → RTP

Find the first meaningful difference.

16. Decide whether you still have a normal RTSP problem

If you do, fix it.

If the source genuinely needs a more flexible route into XProtect, look at ORB Driver.

If the actual challenge is moving, converting, routing or redistributing the video, look at Streaming Engine.

If the workflow also involves remote or edge contribution, look at the wider StreamForce architecture.

Don't add complexity until the evidence tells you why you need it.

Quick reference: symptom → likely area → next test

Symptom Likely area Next test
Works on laptop, fails from Recording Server Network path Test routing, VLAN, firewall and DNS from the Recording Server
VLC works, ODM reports a different URI Incorrect or stale RTSP path Test the URI advertised by the source
TCP works, UDP fails RTP / network transport Check UDP firewalling, NAT and return path
DESCRIBE repeatedly returns 401 Authentication Compare credentials and authentication exchange, and check clock, date and time zone on both ends
DESCRIBE fails entirely URI / auth / RTSP negotiation Fix the control conversation before investigating RTP
SETUP fails Transport negotiation Compare VLC and XProtect SETUP requests
PLAY succeeds but no RTP appears Media delivery Check RTP traffic, firewall and negotiated transport
Stream drops after a repeatable interval Session / keep-alive Check timeout and keep-alive behaviour
URI contains ? parameters PLAY URI handling Check Include URI options on PLAY
Universal Driver adds successfully but video fails Stream not actually validated Test stable live video and capture the exchange
Source fundamentally doesn't behave like a camera Integration model Consider ORB Driver
Source needs conversion, WAN transport or fan-out Video transport Consider Streaming Engine

The important bit

A stream playing in VLC isn't proof that XProtect is wrong.

And XProtect failing doesn't automatically mean the video source is broken.

RTSP is a conversation.

Different clients can request different transports, use slightly different URIs, handle authentication differently or maintain the session in different ways.

So rather than asking:

"Why doesn't XProtect like this RTSP stream?"

I would ask:

"Where does XProtect's conversation first become different from the one that works?"

That is normally where the useful answer is hiding.

And if you eventually prove that the source simply doesn't behave like a conventional IP camera, or that the real challenge is moving the video across an unusual transport path, that is exactly the territory we spend rather a lot of time working in at ORBNET.

If you've got one of those streams that works everywhere except where you actually need it, feel free to send me the source details or the failing RTSP exchange.

I'm also quite interested in hearing the strangest RTSP behaviour you've encountered in the wild.

There are some wonderfully inventive implementations out there.