abpframework/abp · critical · AbpInitializationException
Services have already been configured! If you call Configure
Error message
Services have already been configured! If you call ConfigureServicesAsync method, you must have set AbpApplicationCreationOptions.SkipConfigureServices to true before.
What it means
ConfigureServices() / ConfigureServicesAsync() may run only once per AbpApplication; the private _configuredServices flag enforces this. When you create the app WITHOUT setting AbpApplicationCreationOptions.SkipConfigureServices, the constructor itself calls ConfigureServices() before returning. Calling ConfigureServicesAsync() afterward trips the guard. The flag exists so hosts that need to defer configuration (external DI, tests) can opt out and configure manually.
Source
Thrown at framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs:306
foreach (var module in Modules)
{
if (module.Instance is AbpModule abpModule)
{
abpModule.ServiceConfigurationContext = null!;
}
}
_configuredServices = true;
TryToSetEnvironment(Services);
}
private void CheckMultipleConfigureServices()
{
if (_configuredServices)
{
throw new AbpInitializationException("Services have already been configured! If you call ConfigureServicesAsync method, you must have set AbpApplicationCreationOptions.SkipConfigureServices to true before.");
}
}
//TODO: We can extract a new class for this
public virtual void ConfigureServices()
{
CheckMultipleConfigureServices();
var context = new ServiceConfigurationContext(Services);
Services.AddSingleton(context);
foreach (var module in Modules)
{
if (module.Instance is AbpModule abpModule)
{
abpModule.ServiceConfigurationContext = context;
}
}View on GitHub (pinned to 7ed43b1931)
Solutions
- Pass options => options.SkipConfigureServices = true when creating the app, then call ConfigureServicesAsync() yourself exactly once.
- Or remove the duplicate call and let the framework configure once (the default path does it in the constructor).
- If using AbpApplicationFactory.CreateAsync, it auto-configures - do not call ConfigureServicesAsync again on the result.
Example fix
// before
await AbpApplicationFactory.CreateAsync<MyModule>(services);
await application.ConfigureServicesAsync(); // throws
// after
await AbpApplicationFactory.CreateAsync<MyModule>(services,
options => options.SkipConfigureServices = true);
await application.ConfigureServicesAsync(); Defensive patterns
Strategy: validation
Validate before calling
// When you need to configure manually, opt out of auto-config at creation:
var app = await AbpApplicationFactory.CreateAsync<MyModule>(services,
options => options.SkipConfigureServices = true);
await app.ConfigureServicesAsync(); // now safe, exactly once Prevention
- Pick one initialization path (auto or manual) and do not mix them.
- Document in Program.cs / the test fixture that SkipConfigureServices is intentional when set.
- Grep for ConfigureServicesAsync/ConfigureServices calls to ensure exactly one per app instance.
When it happens
Trigger: Creating the app via a factory that auto-configures, then calling ConfigureServicesAsync() again; or calling ConfigureServices()/ConfigureServicesAsync() twice in code.
Common situations: Migrating from sync to async init and forgetting to remove the old call; a test harness that re-inits the same app; mixing AddApplicationAsync (auto-configures) with a manual ConfigureServicesAsync.
Related errors
- An error occurred during PreConfigureServicesAsync phase of
- An error occurred during ConfigureServicesAsync phase of the
- An error occurred during PostConfigureServicesAsync phase of
- An error occurred during PreConfigureServices phase of the m
- An error occurred during ConfigureServices phase of the modu
AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13).
Data as JSON: /api/errors/458dbb00d88dc2fe.
Report an issue: GitHub.