{"record":{"id":"7c9fb6bbb13b5c00","repo":"LuckyPennySoftware/MediatR","slug":"the-generic-handler-registration-process-timed-out","errorCode":null,"errorMessage":"The generic handler registration process timed out.","messagePattern":"The generic handler registration process timed out\\.","errorType":"exception","errorClass":"TimeoutException","httpStatus":null,"severity":"error","filePath":"src/MediatR/Registration/ServiceRegistrar.cs","lineNumber":39,"sourceCode":"    public static void SetGenericRequestHandlerRegistrationLimitations(MediatRServiceConfiguration configuration)\n    {\n        MaxGenericTypeParameters = configuration.MaxGenericTypeParameters;\n        MaxTypesClosing = configuration.MaxTypesClosing;\n        MaxGenericTypeRegistrations = configuration.MaxGenericTypeRegistrations;\n        RegistrationTimeout = configuration.RegistrationTimeout;\n    }\n\n    public static void AddMediatRClassesWithTimeout(IServiceCollection services, MediatRServiceConfiguration configuration)\n    {\n        using(var cts = new CancellationTokenSource(RegistrationTimeout))\n        {\n            try\n            {\n                AddMediatRClasses(services, configuration, cts.Token);\n            }\n            catch (OperationCanceledException)\n            {\n                throw new TimeoutException(\"The generic handler registration process timed out.\");\n            }\n        }\n    }\n\n    public static void AddMediatRClasses(IServiceCollection services, MediatRServiceConfiguration configuration, CancellationToken cancellationToken = default)\n    {   \n\n        var assembliesToScan = configuration.AssembliesToRegister.Distinct().ToArray();\n\n        ConnectImplementationsToTypesClosing(typeof(IRequestHandler<,>), services, assembliesToScan, false, configuration, cancellationToken);\n        ConnectImplementationsToTypesClosing(typeof(IRequestHandler<>), services, assembliesToScan, false, configuration, cancellationToken);\n        ConnectImplementationsToTypesClosing(typeof(INotificationHandler<>), services, assembliesToScan, true, configuration);\n        ConnectImplementationsToTypesClosing(typeof(IStreamRequestHandler<,>), services, assembliesToScan, false, configuration);\n        ConnectImplementationsToTypesClosing(typeof(IRequestExceptionHandler<,,>), services, assembliesToScan, true, configuration);\n        ConnectImplementationsToTypesClosing(typeof(IRequestExceptionAction<,>), services, assembliesToScan, true, configuration);\n\n        if (configuration.AutoRegisterRequestProcessors)\n        {","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/LuckyPennySoftware/MediatR/blob/916ef1b3d68ccdc96db8f914eaf1b32fc7db52c5/src/MediatR/Registration/ServiceRegistrar.cs#L21-L57","documentation":"Thrown by AddMediatRClassesWithTimeout when scanning assemblies and connecting handler implementations takes longer than RegistrationTimeout (default 15s). The internal CancellationTokenSource cancels AddMediatRClasses; the OperationCanceledException is caught and rewrapped as TimeoutException.","triggerScenarios":"Calling services.AddMediatR(...) in an assembly set with a very large number of types, expensive reflection, heavy disk-loaded assemblies, or a slow/debugger-attached host that cannot complete ConnectImplementationsToTypesClosing within 15 seconds.","commonSituations":"Registering dozens of assemblies; cold start under debugger; slow network/UNC assembly loads; very large dependency graphs causing combinatorial generic-closing work; an unusually low RegistrationTimeout set by the user.","solutions":["Raise RegistrationTimeout: cfg.RegistrationTimeout = TimeSpan.FromMinutes(2); before AddMediatR scans.","Narrow AssembliesToRegister to only the assemblies that actually contain handlers (use cfg.RegisterServicesFromAssembly(typeof(MyMarker).Assembly) rather than AppDomain.GetAssemblies()).","Profile startup: warm the JIT, run without the debugger attached, defer non-essential assembly loads.","Reduce combinatorial generic-handler blow-ups (see MaxGenericTypeRegistrations) which slow registration."],"exampleFix":"// before\nservices.AddMediatR(cfg =>\n{\n    cfg.RegisterServicesFromAssemblies(typeof(A).Assembly, typeof(B).Assembly,\n        typeof(C).Assembly, typeof(D).Assembly); // many assemblies\n});\n\n// after\nservices.AddMediatR(cfg =>\n{\n    cfg.RegistrationTimeout = TimeSpan.FromMinutes(1);\n    cfg.RegisterServicesFromAssembly(typeof(MyHandler).Assembly);\n});","handlingStrategy":"validation","validationCode":"// Before AddMediatR, set a timeout appropriate to your assembly set\ncfg.RegistrationTimeout = TimeSpan.FromMinutes(1);\n// And scope the assemblies scanned\ncfg.RegisterServicesFromAssembly(typeof(MyHandler).Assembly);","typeGuard":null,"tryCatchPattern":"try { services.AddMediatR(cfg => { /* ... */ }); }\ncatch (TimeoutException ex)\n{\n    logger.LogError(ex, \"MediatR registration timed out; raise RegistrationTimeout or narrow assemblies\");\n    throw;\n}","preventionTips":["Register only assemblies that contain handlers; avoid AppDomain.GetAssemblies().","Set RegistrationTimeout based on measured cold-start cost under the debugger.","Profile startup with a Release build to set a realistic cap."],"tags":["di-registration","startup","timeout","performance"],"backgroundTag":null,"analyzedSha":"916ef1b3d68ccdc96db8f914eaf1b32fc7db52c5","analyzedAt":"2026-08-13T17:57:04.476Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}