Iris warning: “BroadcastLoadedModulesUpdated() called while there are N active ReplicationSystems”

Has anyone seen the Iris Warning below? I’m trying to figure out if I should ignore it or if there is some bug from my project. I’ve scoured the internet and can’t find any information on it.

In both 5.7 and 5.8 I see the following Iris Warning when loading a PIE or Development build:

LogIris: Warning: FInternalNetSerializerDelegates::BroadcastLoadedModulesUpdated() called while
there are 1 active ReplicationSystems. If polymorphic types are registered we may have corrupt
data. A restart of the ReplicationSystem or NetDriver is recommended.

I’m using the Lyra project as a base with a GameFeature Plugin for my core code/content. The GFP has a couple TargetData structs that I use to send projectile spawn data from a GameplayAbility.

I ran some tests with LogModuleManager Verbose, then asked Claude to interpret the logs and trace the warning mechanism from the engine source. Here is its response:

What triggers it (from IrisCoreModule.cpp): FIrisCoreModule listens to
FModuleManager::OnModulesChanged. Any module load while at least one ReplicationSystem exists
starts a ticker; once module loading settles it logs this warning and calls
FInternalNetSerializerDelegates::BroadcastLoadedModulesUpdated(), which lets serializers such as
the polymorphic struct cache refresh their type lists. There is no filter: the warning fires for
any module, whether or not it adds network types.

Which modules load late (packaged, -LogCmds="LogModuleManager Verbose"):

  • Server: AutomationWorker, AutomationController (right after the ReplicationSystem is created
    during the startup map load in FEngineLoop::Init), then PerfCounters (as the game mode’s
    experience starts).
  • Client: AutomationWorker, AutomationController, then Voice (while joining).

None of these register polymorphic net types. The polymorphic caches report the same counts on
all three machines when the ReplicationSystem is created (GameplayAbilityTargetData 9,
GameplayEffectContext 2, RootMotionSource 6), and they include our game plugin’s
target-data structs, because in a monolithic packaged build all compiled-in types are registered
at startup.

Why it matters: the real risk the message describes is a module that registers a new
polymorphic type (for example a new FGameplayAbilityTargetData subclass) after a connection is
up, so server and client could disagree on type indices. In this case nothing like that happens,
so the warning looks like a false positive. It is still noisy, and plugin authors can’t easily
tell a harmless case from a real one.

Perhaps the warning is triggering because the GFP is dynamically loading my TargetData structs. I could try to migrate my GFP to a normal Plugin, but I would rather not. I don’t see anything in the Iris documentation that says TargetData can’t be dynamically loaded.

A few questions if a UE dev is reading this:

  1. Is it safe to ignore when the late modules add no polymorphic types?
  2. Is there a supported way to avoid it, for example loading AutomationWorker, AutomationController, PerfCounters and Voice before the NetDriver is created, or a setting to silence it?
  3. Could Iris check whether the polymorphic type lists actually changed before warning?