.NET SDK Troubleshooting
Solutions for .NET-specific issues with Toggly feature flags.
Installation Issues
NuGet Package Not Found
# Verify package name
dotnet add package Toggly.FeatureManagement
# Or specific sub-packages
dotnet add package Toggly.FeatureManagement.RavenDB
dotnet add package Toggly.FeatureManagement.HealthChecks
dotnet add package Toggly.FeatureManagement.Web
Version Compatibility
Ensure you're using compatible versions:
- .NET 6.0+ required
- ASP.NET Core 6.0+ for web features
- Check package dependencies in your
.csproj
Dependency Injection Issues
Service Not Registered
// ❌ Common mistake - not registering services
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Missing Toggly registration!
}
}
// ✅ Correct - register Toggly services
public void ConfigureServices(IServiceCollection services)
{
services.AddToggly(options => {
options.AppKey = Configuration["Toggly:AppKey"];
options.Environment = Configuration["Toggly:Environment"];
});
}
Constructor Injection Failing
// Verify IFeatureManager is registered
public class MyController : ControllerBase
{
private readonly IFeatureManager _featureManager;
public MyController(IFeatureManager featureManager)
{
_featureManager = featureManager ?? throw new ArgumentNullException(nameof(featureManager));
}
}
Configuration Issues
API Key Not Found
// Check appsettings.json
{
"Toggly": {
"AppKey": "your-app-key",
"Environment": "production"
}
}
// Verify configuration is loaded
var appKey = Configuration["Toggly:AppKey"];
if (string.IsNullOrEmpty(appKey))
{
throw new Exception("Toggly AppKey not configured");
}
Environment Variables
// Using environment variables
services.AddToggly(options => {
options.AppKey = Environment.GetEnvironmentVariable("TOGGLY_APP_KEY");
options.Environment = Environment.GetEnvironmentVariable("TOGGLY_ENVIRONMENT");
});
Evaluation Issues
Async/Await Problems
// ❌ Wrong - blocking async call
public IActionResult Index()
{
var isEnabled = _featureManager.IsEnabledAsync("my-feature").Result; // DON'T!
return View();
}
// ✅ Correct - async all the way
public async Task<IActionResult> Index()
{
var isEnabled = await _featureManager.IsEnabledAsync("my-feature");
return View();
}
Context Not Being Passed
// For user-specific targeting
var context = new FeatureContext
{
UserId = "user-123",
Traits = new Dictionary<string, object>
{
["plan"] = "premium"
}
};
var isEnabled = await _featureManager.IsEnabledAsync("premium-feature", context);
MVC/Razor Issues
Feature Tag Helper Not Working
@* Ensure tag helper is registered *@
@addTagHelper *, Toggly.FeatureManagement.Web
@* Then use it *@
<feature name="my-feature">
<p>This content is feature-flagged</p>
</feature>
View Component Issues
// Register view component services
services.AddToggly(options => { ... })
.AddViewComponents();
Caching Issues
Stale Flag Values
// Force refresh
await _togglyService.RefreshAsync();
// Or configure shorter cache duration
services.AddToggly(options => {
options.AppKey = Configuration["Toggly:AppKey"];
options.Environment = Configuration["Toggly:Environment"];
options.CacheDuration = TimeSpan.FromMinutes(1); // Refresh every minute
});
Distributed Cache Issues
// Verify distributed cache is configured
services.AddStackExchangeRedisCache(options => {
options.Configuration = Configuration["Redis:Connection"];
});
// Then enable for Toggly
services.AddToggly(options => { ... })
.WithDistributedCache(TimeSpan.FromMinutes(5));
Performance Issues
Slow Evaluations
// Use caching
services.AddToggly(options => { ... })
.WithMemoryCache(TimeSpan.FromMinutes(5));
// Or distributed cache for multi-server
services.AddToggly(options => { ... })
.WithDistributedCache(TimeSpan.FromMinutes(5));
Too Many HTTP Calls
// Enable snapshot mode - fetch all flags at once
services.AddToggly(options => {
options.AppKey = Configuration["Toggly:AppKey"];
options.Environment = Configuration["Toggly:Environment"];
options.UseSnapshotProvider = true; // Reduces API calls
});
Authentication Issues
See General Authentication Guide.
API Key in appsettings.json
{
"Toggly": {
"AppKey": "your-app-key-here",
"Environment": "production"
}
}
Using Azure Key Vault
// Load from Key Vault
var keyVaultUrl = new Uri(Configuration["KeyVault:Url"]);
var credential = new DefaultAzureCredential();
var client = new SecretClient(keyVaultUrl, credential);
var appKey = await client.GetSecretAsync("TogglyAppKey");
services.AddToggly(options => {
options.AppKey = appKey.Value.Value;
options.Environment = Configuration["Toggly:Environment"];
});
Hangfire Integration Issues
Jobs Not Running
// Verify Hangfire is configured
services.AddHangfire(config => config.UseMemoryStorage());
services.AddHangfireServer();
// Register Toggly jobs
services.AddToggly(options => { ... })
.AddHangfireJobs();
Background Job Errors
Check Hangfire dashboard for errors:
- Navigate to
/hangfire - Check failed jobs
- View exception details
Health Checks
Health Check Always Unhealthy
// Verify health check registration
services.AddToggly(options => { ... })
.AddHealthChecks();
// Ensure endpoint is mapped
app.MapHealthChecks("/health");
// Check health endpoint
// GET https://your-app/health
Common Mistakes
1. Not Registering Services
// Must call AddToggly in ConfigureServices
services.AddToggly(options => { ... });
2. Using Synchronous Code
// ❌ Don't block async code
var result = _featureManager.IsEnabledAsync("feature").Result;
// ✅ Use async/await
var result = await _featureManager.IsEnabledAsync("feature");
3. Wrong Configuration Section
// ❌ Wrong section name
{
"FeatureFlags": { ... }
}
// ✅ Correct section name
{
"Toggly": {
"AppKey": "...",
"Environment": "..."
}
}
Debugging
Enable Logging
// Add logging in Startup
services.AddLogging(builder => {
builder.AddConsole();
builder.AddDebug();
builder.SetMinimumLevel(LogLevel.Debug);
});
// Toggly will log debug information
Check SDK State
// Inject ITogglyService to check state
public class DebugController : ControllerBase
{
private readonly ITogglyService _toggly;
public DebugController(ITogglyService toggly)
{
_toggly = toggly;
}
[HttpGet("debug/toggly")]
public async Task<IActionResult> DebugToggly()
{
var definitions = await _toggly.GetDefinitionsAsync();
return Ok(new {
initialized = _toggly.IsInitialized,
flagCount = definitions?.Count ?? 0,
environment = _toggly.Environment
});
}
}
Invalid signature on startup
Symptom: Error|Invalid signature|source=Toggly.FeatureManagement.TogglyFeatureProvider shortly after Toggly initialized, then a successful HTTP refresh stores FeatureSnapshots/....
Cause: Older packages re-serialized stored feature models when verifying the snapshot signature. Storage round-trips (especially RavenDB) changed the JSON bytes.
Fix:
- Upgrade to Toggly.FeatureManagement 3.3.0+ (stores
SignedDefsJson). - Clear the persisted snapshot once:
ClearPersistedSnapshotsAsync()or delete theFeatureSnapshots/...document. - Let the next refresh rewrite the snapshot with raw signed defs.
From 3.4.0+, signed mode also refuses snapshots that still lack
SignedDefsJson (no unverified soft-load). Clear and refresh as above.
See Reliability.
Missing ETag warnings
Symptom: Response did not include ETag or X-Definitions-Revision header on every refresh.
Cause: Unquoted ETag values are not exposed on HttpResponseMessage.Headers.ETag. 3.3.0+ also reads raw ETag header values and X-Definitions-Revision. Ensure the Definitions worker sends quoted ETags (and keeps X-Definitions-Revision unquoted as the raw revision).
Getting More Help
- General issues: Common Issues
- Authentication: Auth Guide
- Full .NET Docs: .NET SDK Documentation
- Community: GitHub Discussions
- Support: [email protected]