diff --git a/homeassistant/components/nest/camera_sdm.py b/homeassistant/components/nest/camera_sdm.py
index 99234c3de8a8647efd4960ab3ee2bd0ded6caab0..abebc8db3efe4de93e434705f74114eecef283d1 100644
--- a/homeassistant/components/nest/camera_sdm.py
+++ b/homeassistant/components/nest/camera_sdm.py
@@ -3,9 +3,11 @@ from __future__ import annotations
 
 from collections.abc import Callable
 import datetime
+import io
 import logging
 from typing import Any
 
+from PIL import Image, ImageDraw, ImageFilter
 from google_nest_sdm.camera_traits import (
     CameraEventImageTrait,
     CameraImageTrait,
@@ -38,6 +40,15 @@ _LOGGER = logging.getLogger(__name__)
 # Used to schedule an alarm to refresh the stream before expiration
 STREAM_EXPIRATION_BUFFER = datetime.timedelta(seconds=30)
 
+# The Google Home app dispays a placeholder image that appears as a faint
+# light source (dim, blurred sphere) giving the user an indication the camera
+# is available, not just a blank screen. These constants define a blurred
+# ellipse at the top left of the thumbnail.
+PLACEHOLDER_ELLIPSE_BLUR = 0.1
+PLACEHOLDER_ELLIPSE_XY = [-0.4, 0.3, 0.3, 0.4]
+PLACEHOLDER_OVERLAY_COLOR = "#ffffff"
+PLACEHOLDER_ELLIPSE_OPACITY = 255
+
 
 async def async_setup_sdm_entry(
     hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
@@ -62,6 +73,30 @@ async def async_setup_sdm_entry(
     async_add_entities(entities)
 
 
+def placeholder_image(width: int | None = None, height: int | None = None) -> Image:
+    """Return a camera image preview for cameras without live thumbnails."""
+    if not width or not height:
+        return Image.new("RGB", (1, 1))
+    # Draw a dark scene with a fake light source
+    blank = Image.new("RGB", (width, height))
+    overlay = Image.new("RGB", blank.size, color=PLACEHOLDER_OVERLAY_COLOR)
+    ellipse = Image.new("L", blank.size, color=0)
+    draw = ImageDraw.Draw(ellipse)
+    draw.ellipse(
+        (
+            width * PLACEHOLDER_ELLIPSE_XY[0],
+            height * PLACEHOLDER_ELLIPSE_XY[1],
+            width * PLACEHOLDER_ELLIPSE_XY[2],
+            height * PLACEHOLDER_ELLIPSE_XY[3],
+        ),
+        fill=PLACEHOLDER_ELLIPSE_OPACITY,
+    )
+    mask = ellipse.filter(
+        ImageFilter.GaussianBlur(radius=width * PLACEHOLDER_ELLIPSE_BLUR)
+    )
+    return Image.composite(overlay, blank, mask)
+
+
 class NestCamera(Camera):
     """Devices that support cameras."""
 
@@ -212,7 +247,14 @@ class NestCamera(Camera):
         # Fetch still image from the live stream
         stream_url = await self.stream_source()
         if not stream_url:
-            return None
+            if self.frontend_stream_type != STREAM_TYPE_WEB_RTC:
+                return None
+            # Nest Web RTC cams only have image previews for events, and not
+            # for "now" by design to save batter, and need a placeholder.
+            image = placeholder_image(width=width, height=height)
+            with io.BytesIO() as content:
+                image.save(content, format="JPEG", optimize=True)
+                return content.getvalue()
         return await async_get_image(self.hass, stream_url, output_format=IMAGE_JPEG)
 
     async def _async_active_event_image(self) -> bytes | None:
diff --git a/tests/components/nest/test_camera_sdm.py b/tests/components/nest/test_camera_sdm.py
index b7637bf3e2e18d92d4ace5e1db82b54abb6cf4fb..1ac1b4ca6f960ca5cda37bc1ca5c31e6bcaca5dd 100644
--- a/tests/components/nest/test_camera_sdm.py
+++ b/tests/components/nest/test_camera_sdm.py
@@ -135,7 +135,7 @@ async def fire_alarm(hass, point_in_time):
         await hass.async_block_till_done()
 
 
-async def async_get_image(hass):
+async def async_get_image(hass, width=None, height=None):
     """Get image from the camera, a wrapper around camera.async_get_image."""
     # Note: this patches ImageFrame to simulate decoding an image from a live
     # stream, however the test may not use it. Tests assert on the image
@@ -145,7 +145,9 @@ async def async_get_image(hass):
         autopatch=True,
         return_value=IMAGE_BYTES_FROM_STREAM,
     ):
-        return await camera.async_get_image(hass, "camera.my_camera")
+        return await camera.async_get_image(
+            hass, "camera.my_camera", width=width, height=height
+        )
 
 
 async def test_no_devices(hass):
@@ -721,9 +723,11 @@ async def test_camera_web_rtc(hass, auth, hass_ws_client):
     assert msg["success"]
     assert msg["result"]["answer"] == "v=0\r\ns=-\r\n"
 
-    # Nest WebRTC cameras do not support a still image
-    with pytest.raises(HomeAssistantError):
-        await async_get_image(hass)
+    # Nest WebRTC cameras return a placeholder
+    content = await async_get_image(hass)
+    assert content.content_type == "image/jpeg"
+    content = await async_get_image(hass, width=1024, height=768)
+    assert content.content_type == "image/jpeg"
 
 
 async def test_camera_web_rtc_unsupported(hass, auth, hass_ws_client):