diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md
index 1b95527c0e..fbef1d9d28 100644
--- a/com.unity.netcode.gameobjects/CHANGELOG.md
+++ b/com.unity.netcode.gameobjects/CHANGELOG.md
@@ -23,6 +23,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
### Fixed
+- Fixed issue where an attachable could log an error upon being de-spawned during shutdown. (#3895)
- NestedNetworkVariables initialized with no value no longer throw an error. (#3891)
### Security
diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/AttachableBehaviour.cs b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/AttachableBehaviour.cs
index 9f97ca7bca..7038e74cd1 100644
--- a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/AttachableBehaviour.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/AttachableBehaviour.cs
@@ -278,7 +278,7 @@ internal void ForceDetach()
///
public override void OnNetworkPreDespawn()
{
- if (AutoDetach.HasFlag(AutoDetachTypes.OnDespawn))
+ if (NetworkManager.ShutdownInProgress || AutoDetach.HasFlag(AutoDetachTypes.OnDespawn))
{
ForceDetach();
}
@@ -474,10 +474,11 @@ internal void InternalDetach()
///
public void Detach()
{
- if (!gameObject)
+ if (!gameObject || NetworkObject == null || NetworkManager == null || NetworkManager.ShutdownInProgress)
{
return;
}
+
if (!IsSpawned)
{
NetworkLog.LogError($"[{name}][Detach][Not Spawned] Cannot detach if not spawned!");
diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectNetworkClientOwnedObjectsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectNetworkClientOwnedObjectsTests.cs
index 279b4896ef..d59feae840 100644
--- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectNetworkClientOwnedObjectsTests.cs
+++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectNetworkClientOwnedObjectsTests.cs
@@ -75,7 +75,7 @@ public IEnumerator WhenOwnershipIsChanged_OwnershipValuesUpdateCorrectly()
Assert.IsFalse(serverBehaviour.IsOwnedByServer);
Assert.AreEqual(m_ClientNetworkManagers[0].LocalClientId, serverBehaviour.OwnerClientId);
- var clientObject = FindObjects.ByType(orderByIdentifier: true).Where((obj) => obj.NetworkManagerOwner == m_ClientNetworkManagers[0]).FirstOrDefault();
+ var clientObject = m_ClientNetworkManagers[0].SpawnManager.SpawnedObjects.ContainsKey(serverObject.NetworkObjectId) ? m_ClientNetworkManagers[0].SpawnManager.SpawnedObjects[serverObject.NetworkObjectId] : null;
Assert.IsNotNull(clientObject);
Assert.IsTrue(clientObject.IsOwner);