System designTroubleshooting

IP camera snapshot stops loading: fix refresh and connection limits

Why an IP camera snapshot URL works then starts returning broken images, how to test the connection pool, cache and network, and the poll rate that holds up.

LumaSpec Vision11 min read Share on LinkedIn

On this page 9 sections
  1. 01Why does an IP camera snapshot work and then stop loading?
  2. 02How many snapshot clients can one IP camera take?
  3. 03Why does the broken image stay even after the network recovers?
  4. 04How do I test whether the camera or the client is at fault?
  5. 05What poll interval and request timeout should I set?
  6. 06What does a factory reset actually fix?
  7. 07When is a stream better than repeated snapshots?
  8. 08Which camera change makes HMI live views reliable?
  9. 09Questions

A snapshot URL that returns clean images for a shift and then starts serving broken frames is one of the most common failures when an IP camera feeds an HMI, SCADA view or web dashboard. It rarely means a broken network. The camera's small embedded web server, the client's cache and the poll loop interact in ways that look random: the image dies after 10 seconds on one installation and after 10 days on another. This guide orders the likely causes, gives a test for each, settles the two settings that prevent a repeat — poll interval and request timeout — and tells you when a factory reset actually helps. It assumes you already have a working snapshot URL; if you are still building the fetch itself, start with grabbing images from an IP camera over an HTTP snapshot URL.

Why does an IP camera snapshot work and then stop loading?

Three causes cover most cases, in this order: overlapping fetches exhaust the camera's small HTTP session pool (some cameras accept one client at a time), a cached failed fetch keeps drawing a broken image, and a wedged camera web server needs a power cycle or factory reset.

The timing pattern is the tell. Pool exhaustion bites harder whenever a second viewer connects or the poll loop stacks requests, so the failure lands at unpredictable moments — mid-shift, after a weekend, exactly when someone opens a phone browser. A cached failure never recovers on its own: the page keeps requesting the same URL, gets the same stored response, and shows the same broken frame even after the camera is healthy again. The message that an image 'contains errors' means the fetch returned something that is not a complete JPEG — usually an HTML error page from a camera that had no session left to serve you. Only the third cause is a camera fault, and it shows up as failure for every client at once.

How many snapshot clients can one IP camera take?

Assume one concurrent snapshot client per camera until you have measured more. Small embedded web servers commonly accept only a handful of HTTP sessions, and some cameras accept exactly one; a second browser, HMI node or polling script opening mid-fetch is enough to break both.

Every snapshot fetch is a full HTTP transaction: TCP connect, request, JPEG body, close. A keep-alive socket can hold a session open between fetches, and a remote-access gateway or proxy in the path counts its own pool against the camera as well. When several people need the same view, do not give each browser its own route to the camera — run one poller and share its output, the way a one-button live view built on a remote snapshot URL does. The same limit runs through all of machine vision: a camera that works in its vendor tool but not in ROS fails for exactly this reason.

Why does the broken image stay even after the network recovers?

Because the image element keeps showing whatever it last decoded, and the failed fetch itself can sit in a cache. Force every fetch to be a unique URL with a cache-busting timestamp, and redraw the image only after a fetch succeeds, so a failure never replaces the last good frame.

Two details make this stick. First, append a changing query parameter — http://192.168.1.88/snapshot.jpg?ts=1712345678 — so neither the browser nor any proxy between serves a stored response. Second, separate the fetch from the draw: request the image with a timeout, and hand it to the visible element only when the bytes decode as a complete JPEG. A failed or truncated fetch then leaves the previous frame on screen and raises an alarm counter instead. In an HMI, run that fetch off the interface's main thread so a hung 5 s request cannot freeze the whole page — the same pattern as keeping image capture off the GUI thread.

How do I test whether the camera or the client is at fault?

Fetch the URL yourself, outside the HMI: a command-line request with a 5 s timeout, repeated 50 times at one request per second, separates a camera problem from a client problem in under two minutes — count how many replies come back with an image content type.

Run the tests in this order:

  1. Fifty fetches at 1 Hz from a PC on the same switch, HMI poller off. Fifty complete JPEG replies mean the camera and network are healthy at that rate, so the fault lives in the client.
  2. Repeat with the HMI polling. Failures that appear only under combined load point at stacked sessions or a rate the camera cannot sustain.
  3. Open a second client mid-test. If the snapshot dies the moment the second viewer connects, you have found the session limit.
  4. Ping through the failure. Ping alive while fetches fail means the camera is up and its web server is stuck; ping dead means power, PoE budget or cabling.
  5. Read the content type of a failed reply. text/html instead of image/jpeg means the camera returned an error page — an exhausted session pool or an expired login, not corruption on the wire.
Symptom Likely cause Fix
Dies after minutes to days, at random times Session pool exhausted by overlapping fetches One outstanding fetch, 2 s interval, 5 s timeout
Broken frame never recovers by itself Client or proxy cached the failed fetch Cache-busting timestamp; redraw only on success
Reply is an error page, not an image Pool empty or login expired Slow the poll; re-authenticate; one client per camera
Dies exactly when a second viewer opens One-session camera Single poller; share its output with viewers
Fails for everyone, ping dead too Power, PoE budget or cabling Fix the physical layer first
Only a reboot recovers it, more often over time Wedged camera web server Firmware update, watchdog, then replacement

If your camera exposes a CGI command rather than a static path, the same tests apply; see capturing a camera image via HTTP CGI.

What poll interval and request timeout should I set?

Start at one fetch every 2 s, never more than one outstanding request, and a 5 s timeout that starts counting the next interval from completion rather than from the schedule — that holds the client to at most one camera session no matter how slow the camera gets.

Worked example. Take a 1280 × 720 JPEG at medium quality, about 150 kB, polled once per second:

bandwidth (bit/s) = image size (kB) × 8,000 × fetch rate (fetches/s) sessions held ≈ fetch rate (fetches/s) × response time (s)

Bandwidth: 150 × 8,000 × 1 = 1,200,000 bit/s ≈ 1.2 Mbit/s, about 1.2% of a 100 Mbit/s link, so line capacity is never the limiting factor in this pattern. Sessions: a healthy camera answering in 0.2 s holds 1 × 0.2 ≈ 0.2 sessions on average. Now let the camera hang: with no timeout and a fetch every 1 s, the client opens one new session each second and never closes an old one, so a camera measured at 4 concurrent sessions fills its pool 4 s after the first hang and rejects everything after — and only its own slow socket cleanup, often tens of seconds, brings it back. That is the whole 'worked, then died' mechanism in one line of arithmetic. Cap the client at one outstanding request with a 5 s timeout and the worst case stays at one held session.

Two camera-side notes. Some cameras generate the JPEG on request and need a few hundred milliseconds before it is ready, so firing the next request before the previous one completes wastes sessions for nothing. And keep the poll loop in a worker, not on the interface thread, or every slow fetch becomes a frozen screen.

What does a factory reset actually fix?

A factory reset clears only the camera-side failure: a web server whose session table or process wedged after days of polling. It fixes nothing about the client that wedged it — pair the reset with a firmware update, and expect the failure back if the poll loop still stacks requests.

Recover in this order. Power-cycle first: it clears a wedged server in seconds and confirms the diagnosis. Update firmware next, because connection-handling fixes ship in firmware regularly. Then add a watchdog — a small script that fetches the snapshot URL once a minute and raises an alarm after three consecutive failures — so the next wedge is caught by an alarm tag instead of an operator staring at a frozen frame. If the wedges keep coming despite a fixed poll loop and current firmware, the camera's web server is wearing out; plan the replacement on your schedule, not the line's.

When is a stream better than repeated snapshots?

Above roughly 2 fetches per second, stop polling and open a stream. One continuous MJPEG or RTSP session replaces thousands of HTTP transactions per hour with a single connection the camera manages itself, and it is the better default for any live view people watch all day.

The boundary is human, not technical: a polled frame every 1 to 2 s is fine for checking that a machine still runs, while anything that looks like video needs the stream. MJPEG holds one long-lived connection per viewer, so it behaves far better for one viewer but still starves a one-session camera the moment a second one connects — the one-client rule does not go away. For machine-vision logic the same choice bites differently: a locate that works in teach but fails at run time is often a stream-versus-snapshot mismatch rather than a network fault. To put the stream on screen, follow displaying an RTSP camera stream in an HMI; for browser lines, embedding a live camera feed in a web dashboard is the equivalent.

Which camera change makes HMI live views reliable?

If the snapshot endpoint itself is the unreliable part, change the architecture, not the poll rate: a GigE Vision camera holds one streaming session instead of one HTTP transaction per frame, and a smart camera inspects on the device and hands your HMI a result.

This is the decision to make when the camera on the wall is a surveillance-style device whose HTTP endpoint you cannot size or configure. Area scan cameras stream over GigE, USB3, 10GigE or CoaXPress through their SDKs — one connection, one buffer queue, no per-frame HTTP. The MV-CU020-90GC, a 2.5 MP GigE camera with a C-mount and a global shutter, is a typical pick when the HMI view and occasional frame grabs share one camera.

Area scan camerasHikrobot MV-CU020-90GC 2.5 MP Area Scan Camera, GigE, GMAX4002, ColorMV-CU020-90GC
Sensor format
1/1.7"
Lens mount
C-mount
Interface
GigE
Resolution
Up to 3 MP
$309.00View partBuild a system with it

When the goal is a decision rather than a picture for people, smart cameras run the inspection where they stand. The LS-SMC-0063 (1.6 MP, GigE) captures at 60 fps with a built-in 16 mm lens, so the HMI receives pass and fail signals instead of fresh images to judge by eye.

Smart cameras & vision sensors1.6 MP smart camera, 60 fps, 16 mm lens, white light (polarized, transparent light) (LS-SMC-0063)LS-SMC-0063
Interface
GigE
Resolution
Up to 3 MP
$1,110.00View part

Not sure which fits the view you are building? The camera finder filters by interface, resolution and shutter, or configure a camera step by step; every order includes free expert support from our applications team.

Prevention, in six lines:

  • One poller per camera, staggered by half the interval when you run several.
  • 2 s or slower per fetch for a polled view; a stream above 2 fetches per second.
  • One outstanding request, 5 s timeout, redraw only after a clean decode.
  • Cache-busting timestamp on every fetch.
  • Watchdog alarm after three consecutive failed fetches.
  • Firmware kept current; settings recorded before any factory reset.

More integration patterns live on the systems topic page.

Questions

How do I measure my camera's maximum concurrent HTTP sessions?

Open two parallel command-line fetches of the snapshot URL, each with a 5 s timeout, and double the count until a reply comes back late, truncated or non-image. The highest count where every reply is still a complete JPEG is the working limit; design to one below it. Some camera API manuals state the session limit outright, so read the interface chapter before you test.

Can I poll two cameras from one HMI page?

Yes. Each camera has its own session pool, so one poller per camera is safe. Stagger the fetches by half the interval so two cameras never fire in the same instant, and keep each poller at one outstanding request. The failing case is two clients on one camera: a browser preview plus an HMI poller is already enough to exhaust a one-session camera.

Why does a snapshot URL need a login again after the camera reboots?

Cameras that issue a session token refuse every fetch once the token ages out or a reboot clears it, and they answer with a login page instead of a JPEG, which the HMI shows as a broken image. Fetch a fresh session after any reboot, or switch to the camera's documented per-request credentials so no state survives between fetches.

Why is my polled snapshot half-drawn rather than broken?

A half-drawn or torn frame means the client started drawing bytes that never finished arriving, usually because the fetch was interrupted mid-transfer or two writes hit the same image element. Fetch into a separate buffer with a timeout and assign it to the display only after it decodes as a complete JPEG; a truncated file fails to decode and the last good frame stays on screen.

How often should a condition-monitoring tile refresh its snapshot?

Every 5 to 10 s is usually enough for a tile that answers whether the machine still runs, and it leaves the camera's session pool almost idle. Use 1 to 2 s only when a person is actively watching. Below about 500 ms per fetch the traffic pattern is a video stream, so open MJPEG or RTSP instead of polling.