Open Closed

Confirmation email is not sent when a user is created #10931


User avatar
0
VMPProgramador created

When a user is created through the admin UI with Send confirmation email enabled, the user is created successfully, but no confirmation email is sent.

However, clicking Verify on the "Confirm user" page sends the email successfully.

Error

When processing the user-created event through RabbitMQ, AccountIdentityUserCreatedEventHandler fails while generating the confirmation token, with the following exception:

A DbContext can only be created inside a unit of work!
   at Volo.Abp.Identity.AbpSingleActiveTokenProvider.GenerateAsync(...)
   at Volo.Abp.Account.Emailing.AccountIdentityUserCreatedEventHandler.HandleEventAsync(...)

The exception occurs before the email is sent, so no confirmation email is generated. RabbitMQ repeatedly retries the failed message.

Change tested

In a test environment, the AccountIdentityUserCreatedEventHandler.cs file in the Volo.Abp.Account.Pro.Public.Application project was modified as follows:

Before:

public async Task HandleEventAsync(IdentityUserCreatedEto eventData)

After:

[UnitOfWork]
public virtual async Task HandleEventAsync(IdentityUserCreatedEto eventData)

The following namespace must also be added:

using Volo.Abp.Uow;

No other changes were made to the method.

After this change, the confirmation email was sent successfully, and the unit of work errors no longer appeared in the logs.

Sources

Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

3 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • This happens because the distributed handler (AccountIdentityUserCreatedEventHandler) runs in the RabbitMQ consumer pipeline without an ambient ABP Unit of Work, but it calls Identity token generation (AbpSingleActiveTokenProvider.GenerateAsync(...)), which needs an EF Core DbContext. Without a UOW, ABP throws:

      A DbContext can only be created inside a unit of work!

    • Fix: ensure the handler method is executed inside a Unit of Work via interception:

      1. Add [UnitOfWork]
      2. Make the method virtual (required for ABP’s dynamic proxy interception)
      3. Add using Volo.Abp.Uow;

      Example:

    using System.Threading.Tasks;
      using Volo.Abp.Uow;
    
      public class AccountIdentityUserCreatedEventHandler
      {
          [UnitOfWork]
          public virtual async Task HandleEventAsync(IdentityUserCreatedEto eventData)
          {
              // existing handler code (no other changes needed)
          }
      }
    
    • Why the virtual matters: ABP applies [UnitOfWork] through dynamic proxy interceptors. If the method isn’t virtual, the interceptor won’t run, so no UOW is created, and token generation fails. This matches the behavior you observed and also the known pattern from ABP support Q&A.

    • Alternative (works but usually not necessary if interception works): manually begin a UOW inside the handler:

    using var uow = _unitOfWorkManager.Begin();
      // ...
      await uow.CompleteAsync();
    

    But the recommended approach is the attribute + virtual so the infrastructure manages it consistently.

    Links checked:

    • https://abp.io/docs/latest/framework/infrastructure/event-bus/distributed
    • https://abp.io/docs/latest/framework/architecture/domain-driven-design/unit-of-work
    • https://abp.io/support/questions/3201

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    VMPProgramador created

    Could a member of the support team please review this ticket?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Hi,

    AccountIdentityUserCreatedEventHandler doesn't start a unit of work, so it fails when the event comes from RabbitMQ.

    You can use this workaround for now. Add this class to your Application project:

    using System.Threading.Tasks;
    using Volo.Abp.Account.Emailing;
    using Volo.Abp.EventBus.Distributed;
    using Volo.Abp.Identity;
    using Volo.Abp.Settings;
    using Volo.Abp.Uow;
    
    namespace YourProjectName.Account;
    
    public class MyAccountIdentityUserCreatedEventHandler :
        AccountIdentityUserCreatedEventHandler,
        IDistributedEventHandler<IdentityUserCreatedEto>
    {
        public MyAccountIdentityUserCreatedEventHandler(
            IdentityUserManager userManager,
            IAccountEmailer accountEmailer,
            ISettingProvider settingProvider)
            : base(userManager, accountEmailer, settingProvider)
        {
        }
    
        [UnitOfWork]
        public new virtual Task HandleEventAsync(IdentityUserCreatedEto eventData)
        {
            return base.HandleEventAsync(eventData);
        }
    }
    

    Then remove the original handler in the ConfigureServices method of your Application module, so the email isn't sent twice:

    using Volo.Abp.Account.Emailing;
    using Volo.Abp.EventBus.Distributed;
    
    Configure<AbpDistributedEventBusOptions>(options =>
    {
        options.Handlers.Remove<AccountIdentityUserCreatedEventHandler>();
    });
    

    The messages that RabbitMQ is still retrying will also be handled after this change.

    We'll fix this in the next patch release. Your ticket has been refunded.

    Thanks

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on November 02, 2026, 06:56
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.