Repository navigation
download_image() returns 401 on an otherwise working session, and the error body is written as the .jpg #189
Description
Hi, with the assistance of Claude Code, I've created this Bug report. Thanks for your efforts with this code :)
vsure: 2.10.0
Seen via: Home Assistant 2026.7.4 (Container), verisure integration
Hardware: two Verisure SmartCams
The problem
Capturing a SmartCam image works. Downloading it does not. The download returns
401 Unauthorized, and the integration writes the response body straight to
/config/<mediaId>.jpg without checking the status code. camera_image() then
serves that file, so the camera entity returns a 17-byte "image":
$ # via /api/camera_proxy/camera.<name>
len: 17
hex: 34303120556e617574686f72697a65640a
repr: b'401 Unauthorized\n'
In the UI this looks like a broken thumbnail, and the download button in the
more-info dialog produces a file containing the text 401 Unauthorized.
Because self._image_id is then set to that media id, check_imagelist() logs
"The image is the same" on every subsequent call and never retries, so the
camera stays permanently broken until the integration is reloaded.
What works
The same session authenticates fine for everything else. Data updates succeed
every 60 seconds, continuously:
DEBUG [homeassistant.components.verisure] Finished fetching verisure data in 0.142 seconds (success: True)
DEBUG [verisure] Saved cookies: ['vid', 'vs-access', 'vs-trust-<redacted>', 'vs-refresh']
verisure.capture_smartcam also works. Calling it produces a genuinely new
image on the Verisure side, and the media id increments:
DEBUG [homeassistant.components.verisure] Capturing new image from <device label redacted>
DEBUG [homeassistant.components.verisure] Download new image 44317755233692001
DEBUG [homeassistant.components.verisure] Old image_id=44317755233691001
DEBUG [homeassistant.components.verisure] Deleting old image /config/44317755233691001.jpg
The captured photo is visible in the Verisure mobile app, at the expected
timestamp. So the image exists and the account is permitted to view it.
What is ruled out
- Not a stale cache.
homeassistant.reload_config_entryresets the entity,
and the retry fromOld image_id=Nonefails identically. - Not an expired session. The failure reproduces immediately after a fresh
login, on a session whose other API calls are succeeding. - Not one camera. Both SmartCams fail the same way, on different media ids.
- Not account permissions. The photo is viewable in the Verisure app.
- Not an outdated library. vsure 2.10.0 is the newest release.
Steps to reproduce
- Call
verisure.capture_smartcamon a SmartCam entity. - Wait for the next coordinator poll, then request the camera image
(/api/camera_proxy/camera.<name>, or just open the more-info dialog). - The response is 17 bytes of
401 Unauthorized, not a JPEG.
Suspected cause
download_image() in vsure's session.py does send the session cookies:
response = requests.get(
urls.download_image(self._giid, device_label, image_id),
headers={
'APPLICATION_ID': 'PS_PYTHON',
'Accept': 'image/jpeg'},
cookies=self._request_cookies,
stream=True)Since the same cookies work for every other endpoint, the difference is either
the APPLICATION_ID: PS_PYTHON header being rejected on the media endpoint, or
a change to the download URL/auth scheme on Verisure's side. I could not
confirm which from outside the container.
Separate, smaller bug in the same function
Regardless of the 401's cause, download_image() writes the response body to
disk without checking response.status_code. Any error response becomes a
corrupt .jpg. Raising on a non-200 instead would turn this silent corruption
into a visible error, and would stop consumers caching a failure as if it were
an image.
That second part is what makes it permanent downstream: Home Assistant's
camera.py records the media id after the download and then skips every
subsequent fetch as "the image is the same", so one failed download disables
the camera entity until the integration is reloaded. Happy to raise that half
separately against home-assistant/core if you would prefer it split, though
the fix here would prevent it either way.
Activity
persandstrom commentedon Aug 17, 2026
Hi,
Thank you for reporting!
I have changed so that an error is raised if the download commands fail as suggested, however it seems like you do not use the latest python-verisure, i do not recognize the code snippet:
Can you please double check which version you use