You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Title:Samsung TV integration overwrites config entry unique_id when TV regenerates UPnP UUID, creating duplicate entities
The problem
Some Samsung TVs (particularly older models like the 2017 UN43MU6300) regenerate their UPnP UUID on every reboot or power cycle. When Home Assistant rediscovers the TV via SSDP, the samsungtv config flow's _async_update_existing_matching_entry() method overwrites the config entry's unique_id with the new UUID.
Since entity unique_id values are derived from config_entry.unique_id (in SamsungTVEntity.__init__), this causes:
All existing entities become orphaned — their unique_id no longer matches the config entry
New duplicate entities are created with the new UUID as their unique_id
Automations and dashboard tiles break because they reference the old entity registry entries
The device registry accumulates multiple UUID identifiers over time
This cycle repeats on every TV reboot, creating an ever-growing list of orphaned entities.
Root cause
In config_flow.py, _async_get_existing_matching_entry() returns is_unique_match=True for both MAC matches and UPnP UUID matches:
# Line 376-381forentryinself._async_current_entries(include_ignore=False):
if (self._macandself._mac==entry.data.get(CONF_MAC)) or (
self._upnp_udnandself._upnp_udn==entry.unique_id
):
returnentry, True# <-- MAC match returns is_unique_match=True
Then in _async_update_existing_matching_entry(), the unique_id is overwritten when is_unique_match=True and the IDs differ:
# Line 401-405ifself.unique_idand (
entry.unique_idisNoneor (is_unique_matchandself.unique_id!=entry.unique_id)
):
entry_kw_args["unique_id"] =self.unique_id
When the TV reboots with a new UUID, the flow discovers it via SSDP, matches the existing entry by MAC address (is_unique_match=True), sees a different unique_id, and overwrites it.
What version of Home Assistant Core has the issue?
core-2026.4.1
What was the last working version of Home Assistant Core?
(unknown — this has likely been present for a long time)
Affected TV: Samsung UN43MU6300 (2017), websocket method on port 8002.
Over the course of a few weeks, the device registry accumulated 4 different UPnP UUIDs as identifiers, and 6 duplicate entities (3 pairs of media_player + remote with _2, _3 suffixes).
Workaround: A custom integration that monkey-patches _async_update_existing_matching_entry to skip the unique_id update when the existing entry already has one set.
Rationale: If the config entry already has a unique_id, it should be treated as the stable identity. The UUID rotation on older TVs is a firmware quirk, not a legitimate identity change. Overwriting the unique_id breaks entity identity across the board.
Option B: Distinguish MAC match from UUID match (more precise fix)
# In _async_get_existing_matching_entry(), change the return to distinguish# MAC-only matches from UUID matches:@callbackdef_async_get_existing_matching_entry(
self,
) ->tuple[ConfigEntry|None, bool]:
"""Get first existing matching entry (prefer unique id)."""matching_host_entry: ConfigEntry|None=Noneforentryinself._async_current_entries(include_ignore=False):
# UUID match — this IS a unique_id matchifself._upnp_udnandself._upnp_udn==entry.unique_id:
LOGGER.debug("Found entry matching unique_id for %s", self._host)
returnentry, True# MAC match — same device, but NOT a unique_id matchifself._macandself._mac==entry.data.get(CONF_MAC):
LOGGER.debug("Found entry matching MAC for %s", self._host)
returnentry, Falseifentry.data[CONF_HOST] ==self._host:
LOGGER.debug("Found entry matching host for %s", self._host)
matching_host_entry=entryreturnmatching_host_entry, False
Rationale:is_unique_match should only be True when the match was actually on the unique_id (UUID), not when it was on the MAC address. A MAC match means "same physical device" but says nothing about whether the UUID should be updated. With this change, _async_update_existing_matching_entry will only overwrite the unique_id when entry.unique_id is None (for MAC-only matches), which is the correct behavior.
Recommended approach
Option B is the better fix because:
It preserves the original intent: is_unique_match should mean "matched by unique_id"
It correctly handles the case where entry.unique_id is None (first-time setup — UUID gets populated)
It doesn't overwrite the UUID when the match was by MAC, which is the root cause
Option A would prevent legitimate UUID updates even when the match was on UUID (though it's unclear when that would be needed)
Test case to add
asyncdeftest_ssdp_update_does_not_overwrite_unique_id_on_mac_match(
hass: HomeAssistant,
) ->None:
"""Test that SSDP rediscovery with a new UUID does not overwrite an existing unique_id when matched by MAC."""entry=MockConfigEntry(
domain=DOMAIN,
data={
CONF_HOST: "192.168.16.71",
CONF_MAC: "9c:8c:6e:6b:ae:07",
CONF_METHOD: "websocket",
},
unique_id="original-uuid-1234",
)
entry.add_to_hass(hass)
result=awaithass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_SSDP},
data=ssdp.SsdpServiceInfo(
ssdp_usn="uuid:new-uuid-5678::...",
ssdp_st="urn:...",
upnp={
ATTR_UPNP_UDN: "uuid:new-uuid-5678",
ATTR_UPNP_FRIENDLY_NAME: "Samsung TV",
ATTR_UPNP_MANUFACTURER: "Samsung",
},
ssdp_location="http://192.168.16.71:9197/dmr",
),
)
# Should abort (entry already exists), and unique_id should NOT be changedassertresult["type"] isFlowResultType.ABORTassertentry.unique_id=="original-uuid-1234"# NOT "new-uuid-5678"
Upstream Issue & PR Draft for home-assistant/core
GitHub Issue
Title:
Samsung TV integration overwrites config entry unique_id when TV regenerates UPnP UUID, creating duplicate entitiesThe problem
Some Samsung TVs (particularly older models like the 2017 UN43MU6300) regenerate their UPnP UUID on every reboot or power cycle. When Home Assistant rediscovers the TV via SSDP, the
samsungtvconfig flow's_async_update_existing_matching_entry()method overwrites the config entry'sunique_idwith the new UUID.Since entity
unique_idvalues are derived fromconfig_entry.unique_id(inSamsungTVEntity.__init__), this causes:unique_idno longer matches the config entryunique_idThis cycle repeats on every TV reboot, creating an ever-growing list of orphaned entities.
Root cause
In
config_flow.py,_async_get_existing_matching_entry()returnsis_unique_match=Truefor both MAC matches and UPnP UUID matches:Then in
_async_update_existing_matching_entry(), theunique_idis overwritten whenis_unique_match=Trueand the IDs differ:When the TV reboots with a new UUID, the flow discovers it via SSDP, matches the existing entry by MAC address (
is_unique_match=True), sees a differentunique_id, and overwrites it.What version of Home Assistant Core has the issue?
core-2026.4.1
What was the last working version of Home Assistant Core?
(unknown — this has likely been present for a long time)
What type of installation are you running?
Home Assistant Container
Integration causing the issue
Samsung Smart TV
Link to integration documentation on our website
https://www.home-assistant.io/integrations/samsungtv
Additional information
Affected TV: Samsung UN43MU6300 (2017), websocket method on port 8002.
Over the course of a few weeks, the device registry accumulated 4 different UPnP UUIDs as identifiers, and 6 duplicate entities (3 pairs of
media_player+remotewith_2,_3suffixes).Workaround: A custom integration that monkey-patches
_async_update_existing_matching_entryto skip theunique_idupdate when the existing entry already has one set.Proposed Code Change
File:
homeassistant/components/samsungtv/config_flow.pyOption A: Don't overwrite unique_id when entry already has one (minimal fix)
Rationale: If the config entry already has a
unique_id, it should be treated as the stable identity. The UUID rotation on older TVs is a firmware quirk, not a legitimate identity change. Overwriting theunique_idbreaks entity identity across the board.Option B: Distinguish MAC match from UUID match (more precise fix)
Rationale:
is_unique_matchshould only beTruewhen the match was actually on theunique_id(UUID), not when it was on the MAC address. A MAC match means "same physical device" but says nothing about whether the UUID should be updated. With this change,_async_update_existing_matching_entrywill only overwrite theunique_idwhenentry.unique_id is None(for MAC-only matches), which is the correct behavior.Recommended approach
Option B is the better fix because:
is_unique_matchshould mean "matched by unique_id"entry.unique_id is None(first-time setup — UUID gets populated)Test case to add
Filing Checklist
home-assistant/core, create a branchhomeassistant/components/samsungtv/config_flow.pytests/components/samsungtv/test_config_flow.py