diff --git a/homeassistant/components/color_extractor/__init__.py b/homeassistant/components/color_extractor/__init__.py
index 0fd9f8a1a2e45fc479eb0d1aa2edebb26d82f0bb..ddd2ae967e4a522fc20536c766965cf6e36e87da 100644
--- a/homeassistant/components/color_extractor/__init__.py
+++ b/homeassistant/components/color_extractor/__init__.py
@@ -27,12 +27,15 @@ import homeassistant.helpers.config_validation as cv
 _LOGGER = logging.getLogger(__name__)
 
 # Extend the existing light.turn_on service schema
-SERVICE_SCHEMA = cv.make_entity_service_schema(
-    {
-        **LIGHT_TURN_ON_SCHEMA,
-        vol.Exclusive(ATTR_PATH, "color_extractor"): cv.isfile,
-        vol.Exclusive(ATTR_URL, "color_extractor"): cv.url,
-    }
+SERVICE_SCHEMA = vol.All(
+    cv.has_at_least_one_key(ATTR_URL, ATTR_PATH),
+    cv.make_entity_service_schema(
+        {
+            **LIGHT_TURN_ON_SCHEMA,
+            vol.Exclusive(ATTR_PATH, "color_extractor"): cv.isfile,
+            vol.Exclusive(ATTR_URL, "color_extractor"): cv.url,
+        }
+    ),
 )
 
 
@@ -63,10 +66,6 @@ async def async_setup(hass, hass_config):
         """Decide which color_extractor method to call based on service."""
         service_data = dict(service_call.data)
 
-        if ATTR_URL not in service_data and ATTR_PATH not in service_data:
-            _LOGGER.error("Missing either required %s or %s key", ATTR_URL, ATTR_PATH)
-            return
-
         try:
             if ATTR_URL in service_data:
                 image_type = "URL"
@@ -110,7 +109,7 @@ async def async_setup(hass, hass_config):
                 "External URL '%s' is not allowed, please add to 'allowlist_external_urls'",
                 url,
             )
-            return
+            return None
 
         _LOGGER.debug("Getting predominant RGB from image URL '%s'", url)
 
@@ -123,7 +122,7 @@ async def async_setup(hass, hass_config):
 
         except (asyncio.TimeoutError, aiohttp.ClientError) as err:
             _LOGGER.error("Failed to get ColorThief image due to HTTPError: %s", err)
-            return
+            return None
 
         content = await response.content.read()
 
@@ -140,7 +139,7 @@ async def async_setup(hass, hass_config):
                 "File path '%s' is not allowed, please add to 'allowlist_external_dirs'",
                 file_path,
             )
-            return
+            return None
 
         _LOGGER.debug("Getting predominant RGB from file path '%s'", file_path)
 
diff --git a/tests/components/color_extractor/test_service.py b/tests/components/color_extractor/test_service.py
index 00b304cae548d50455acb8f5ae5c4332cd5b306d..31b623f1c76257623d8bf74c11a3d8541ae90acb 100644
--- a/tests/components/color_extractor/test_service.py
+++ b/tests/components/color_extractor/test_service.py
@@ -4,6 +4,7 @@ import io
 
 import aiohttp
 import pytest
+from voluptuous.error import MultipleInvalid
 
 from homeassistant.components.color_extractor import (
     ATTR_PATH,
@@ -103,8 +104,11 @@ async def test_missing_url_and_path(hass):
         ATTR_ENTITY_ID: LIGHT_ENTITY,
     }
 
-    await hass.services.async_call(DOMAIN, SERVICE_TURN_ON, service_data, blocking=True)
-    await hass.async_block_till_done()
+    with pytest.raises(MultipleInvalid):
+        await hass.services.async_call(
+            DOMAIN, SERVICE_TURN_ON, service_data, blocking=True
+        )
+        await hass.async_block_till_done()
 
     # check light is still off, unchanged due to bad parameters on service call
     state = hass.states.get(LIGHT_ENTITY)