Microsoft Feature Management Quirks (and How to Survive Them)
Microsoft Feature Management Quirks
Microsoft.FeatureManagement is solid, widely used, and much better than building your own feature flag framework in a caffeine panic. But it has quirks. None are fatal. All are annoying. Most are avoidable if you know where the sharp edges are.
Your Flag Names Are Strings Forever
Feature names are string literals. That means typos compile perfectly and fail at runtime in the most boring way possible.
You configure "NewDashboard" but check "NewDashbaord" in code, then spend an afternoon wondering why the shiny new UI never appears.
Workaround: centralize flag names in constants or a strongly-typed wrapper, and stop scattering raw strings throughout controllers, services, tag helpers, and filters.
Configuration Shape Is Less Forgiving Than It Looks
The library expects a specific configuration layout under FeatureManagement. If you typo the section name, mis-shape EnabledFor, or nest things oddly, flags will not behave as expected.
It usually looks like the system is “ignoring” your config when the real problem is structure.
Workaround: keep one canonical sample config in your repo, validate it in integration tests, and avoid creative JSON art projects in production.
Filter Behavior Depends on Context Quality
PercentageFilter is random per evaluation, so the same user may see different results across requests. That can be fine for coarse rollout, but it surprises teams expecting sticky behavior.
Workaround: if you need stable outcomes per user, use ConsistentPercentageFilter. In ASP.NET Core scenarios, it uses the current principal identity as the user key, then hashes that stable value for deterministic bucket assignment. If identity is missing or changes between requests, your results can still look random.
IsEnabledAsync Everywhere Means You Can Re-Evaluate a Lot
Flag checks are asynchronous and easy to sprinkle everywhere. It feels clean until you realize you’re checking the same flag multiple times in one request path.
Workaround: evaluate once per request or operation, then pass the result through your flow. You get clearer behavior and fewer surprises.
IFeatureManager vs IFeatureManagerSnapshot
You can inject either interface, and that choice matters. In request-heavy applications, snapshot semantics are often what you actually want: consistency for the lifetime of a request.
Workaround: prefer IFeatureManagerSnapshot where consistent per-request behavior matters, and be intentional when using the non-snapshot manager.
None of This Is a Dealbreaker
Microsoft’s feature management library is still a great default choice in .NET. Most pain comes from naming drift, configuration mistakes, and context assumptions — not from the core library itself.
Know the quirks, add a few guardrails, and you can keep the benefits without the mystery bugs.
The framework is fine. Your future self just wants fewer typo-driven incidents.