Common Issues and Troubleshooting
This guide helps you resolve common issues when using TickerQ.
Installation Issues
Package Version Mismatch
Problem: Packages show version conflicts or missing dependencies.
Solution: Ensure all TickerQ packages are the same version:
dotnet add package TickerQ --version 8.0.0
dotnet add package TickerQ.EntityFrameworkCore --version 8.0.0
dotnet add package TickerQ.Dashboard --version 8.0.0Source Generator Not Working
Problem: [TickerFunction] methods not being recognized.
Solution:
- Ensure you're using .NET 8.0 or later
- Restart your IDE (Visual Studio/Rider/VS Code)
- Clean and rebuild the solution:bash
dotnet clean dotnet build - Verify source generator DLL is included in the package
Configuration Issues
Jobs Not Executing
Problem: Jobs are scheduled but never execute.
Solution:
- Verify
UseTickerQ()is called in your application pipeline:csharpapp.UseTickerQ(); - Check start mode:csharp
app.UseTickerQ(TickerQStartMode.Immediate); // Not Manual - Verify job execution time is not in the future
- Check application logs for errors
- Ensure persistence provider is configured correctly
Function Not Found
Problem: Error indicating function name not found.
Solution:
- Ensure function name matches exactly:csharp
[TickerFunction("MyFunction")] // Must match exactly public async Task MyFunction(...) { } // When scheduling Function = "MyFunction" // Same name - Verify source generator ran successfully (check build output)
- Rebuild the project to regenerate function registry
Entity Framework Configuration Issues
Problem: Migrations fail or entities not configured.
Solution:
- If using built-in
TickerQDbContext(recommended), migrations are straightforward:csharpoptions.AddOperationalStore(efOptions => { efOptions.UseTickerQDbContext<TickerQDbContext>(optionsBuilder => { optionsBuilder.UseNpgsql(connectionString); }); }); // Then run migrations dotnet ef migrations add InitialCreate --context TickerQDbContext dotnet ef database update --context TickerQDbContext - If using application DbContext, use
UseApplicationDbContext:csharpoptions.AddOperationalStore<MyApplicationDbContext>(efOptions => { efOptions.UseApplicationDbContext<MyApplicationDbContext>(ConfigurationType.UseModelCustomizer); }); - If conflicts with other
IModelCustomizer, use manual configuration:csharpprotected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.ApplyConfiguration(new TimeTickerConfigurations()); builder.ApplyConfiguration(new CronTickerConfigurations()); builder.ApplyConfiguration(new CronTickerOccurrenceConfigurations()); }
Runtime Issues
Jobs Stuck in InProgress
Problem: Jobs remain in InProgress status and never complete.
Solution:
- Check for unhandled exceptions in job functions
- Verify
CancellationTokenis being checked - Check if job is actually running (dashboard or logs)
- Restart the application to release stuck jobs
- With EF Core, manually update status if needed:csharp
var job = await _context.Set<TimeTickerEntity>().FindAsync(jobId); if (job.Status == TickerStatus.InProgress && job.LockedAt < DateTime.UtcNow.AddMinutes(-30)) { job.Status = TickerStatus.Failed; job.ExceptionMessage = "Job timeout"; await _context.SaveChangesAsync(); }
High Memory Usage
Problem: Application memory usage is high.
Solution:
- Check for memory leaks in job functions
- Ensure proper disposal of resources:csharp
await using var scope = _serviceProvider.CreateAsyncScope(); // Use scope.ServiceProvider - Configure concurrency limits:csharp
options.ConfigureScheduler(scheduler => { scheduler.MaxConcurrency = Environment.ProcessorCount; }); - Clean up old jobs and occurrences regularly
- Check for accumulating request data
Database Connection Issues
Problem: Database connection errors with EF Core.
Solution:
- Verify connection string is correct
- Check database is accessible
- Ensure connection pooling is configured (with built-in
TickerQDbContext):csharpoptions.AddOperationalStore(efOptions => { efOptions.UseTickerQDbContext<TickerQDbContext>(optionsBuilder => { optionsBuilder.UseNpgsql(connectionString, cfg => { cfg.EnableRetryOnFailure(3, TimeSpan.FromSeconds(5), ["40P01"]); }); }); efOptions.SetDbContextPoolSize(34); // Adjust as needed }); - Check database timeout settings
- Monitor connection pool exhaustion
- Enable retry on failure for transient errors (as shown above)
Dashboard Issues
Dashboard Not Loading
Problem: Dashboard UI doesn't load or shows errors.
Solution:
- Verify
UseTickerQ()is called - Check base path configuration:csharp
dashboardOptions.SetBasePath("/tickerq/dashboard"); - Ensure static files middleware is configured
- Check browser console for errors
- Verify authentication is configured correctly
403 Forbidden Errors
Problem: Random 403 responses from dashboard endpoints.
Solution:
- Check authentication configuration
- Verify no authorization policies are blocking requests
- Check middleware ordering (dashboard should be after auth)
- Verify CORS configuration if dashboard is on different domain
- Check route constraints
SignalR Connection Issues
Problem: Real-time updates not working.
Solution:
- Verify SignalR is configured:csharp
builder.Services.AddSignalR(); - Check WebSocket support is enabled
- Verify authentication for SignalR connections
- Check firewall/proxy settings
- Review browser console for connection errors
Redis Issues
Redis Connection Failures
Problem: Cannot connect to Redis.
Solution:
- Verify Redis connection string:csharp
redisOptions.Configuration = "localhost:6379"; - Check Redis server is running
- Verify network connectivity
- Check authentication if required
- Test connection with Redis CLI
Dead Node Detection Not Working
Problem: Dead nodes are not detected.
Solution:
- Verify heartbeat interval:csharp
redisOptions.NodeHeartbeatInterval = TimeSpan.FromMinutes(1); - Check heartbeat TTL (interval + 20 seconds)
- Verify
NodeHeartBeatBackgroundServiceis running - Check Redis connectivity
- Review application logs for heartbeat errors
Performance Issues
Slow Job Execution
Problem: Jobs take too long to execute.
Solution:
- Profile job functions to identify bottlenecks
- Check database query performance
- Verify concurrency settings:csharp
options.ConfigureScheduler(scheduler => { scheduler.MaxConcurrency = Environment.ProcessorCount * 2; }); - Use appropriate priority:csharp
[TickerFunction("FastJob", taskPriority: TickerTaskPriority.High)] - Consider using
LongRunningpriority for CPU-bound tasks
Too Many Concurrent Jobs
Problem: Too many jobs executing simultaneously.
Solution:
- Reduce max concurrency:csharp
options.ConfigureScheduler(scheduler => { scheduler.MaxConcurrency = 5; // Limit to 5 concurrent jobs }); - Use priority system to control execution order
- Implement throttling in job functions
- Schedule jobs with delays to spread load
OpenTelemetry Issues
Traces Not Appearing
Problem: OpenTelemetry traces are not being exported.
Solution:
- Verify OpenTelemetry is configured:csharp
builder.Services.AddOpenTelemetry() .WithTracing(tracing => { tracing.AddSource("TickerQ"); }); - Ensure exporter is added:csharp
tracing.AddConsoleExporter(); // Or other exporter - Verify instrumentation is enabled:csharp
builder.Services.AddTickerQ(options => { options.AddOpenTelemetryInstrumentation(); }); - Check exporter endpoint/configuration
- Review application logs for exporter errors
Best Practices for Troubleshooting
1. Enable Logging
builder.Host.ConfigureLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Debug);
logging.AddConsole();
});2. Use Dashboard
The dashboard provides real-time visibility into:
- Job status
- Active threads
- Next occurrences
- Error messages
3. Check Application Logs
Monitor logs for:
- Exception messages
- Job execution times
- Retry attempts
- Connection errors
4. Verify Configuration
Double-check:
- Package versions match
- Configuration options are correct
- Middleware ordering
- Connection strings
5. Test Incrementally
Start with minimal configuration and add features incrementally:
- Start with core TickerQ (in-memory)
- Add Entity Framework
- Add Dashboard
- Add Redis
- Add OpenTelemetry
Debug Checklist
Use this checklist to systematically debug issues:
Installation & Setup
- [ ] TickerQ package installed correctly
- [ ]
.NET 8.0+target framework - [ ]
AddTickerQ()called in service registration - [ ]
UseTickerQ()called in application pipeline - [ ] No conflicting package versions
Job Definition
- [ ]
[TickerFunction]attribute present - [ ] Function is
publicmethod - [ ] Returns
TaskorTask<T> - [ ] Signature matches:
(TickerFunctionContext, CancellationToken) - [ ] Function name matches exactly (case-sensitive)
Job Scheduling
- [ ] Entity created with valid properties
- [ ]
Functionname matches attribute - [ ]
ExecutionTimeset (for TimeTicker) - [ ] Valid cron expression (for CronTicker - 6-part format)
- [ ] Manager
AddAsynccalled - [ ] Result checked for
IsSucceeded
Execution
- [ ] Job execution time has passed (if scheduled in future)
- [ ] Application is running (not just built)
- [ ] No exceptions in application logs
- [ ] Job status checked (via dashboard or persistence provider)
Persistence (if using EF Core)
- [ ] Database connection working
- [ ] Migrations applied
- [ ] Entity configurations applied
- [ ] DbContext pool configured correctly
Diagnostic Commands
Check Registered Functions
// After UseTickerQ() is called
var functions = TickerFunctionProvider.TickerFunctions;
foreach (var func in functions)
{
Console.WriteLine($"Registered: {func.Key}");
}Check Job Status
// If using EF Core
var job = await _context.Set<TimeTickerEntity>()
.FirstOrDefaultAsync(t => t.Id == jobId);
Console.WriteLine($"Status: {job?.Status}");
Console.WriteLine($"Execution Time: {job?.ExecutionTime}");
Console.WriteLine($"Executed At: {job?.ExecutedAt}");Enable Verbose Logging
builder.Host.ConfigureLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Debug);
logging.AddConsole();
});FAQ
Q: How do I know if TickerQ is running?
A: Check that:
- No exceptions during
UseTickerQ()call - Background services started (check logs)
- Dashboard accessible (if enabled)
- Jobs execute at scheduled times
Q: Can I schedule jobs before UseTickerQ() is called?
A: Yes, but they won't execute until UseTickerQ() is called. Jobs scheduled in the past will execute immediately.
Q: How do I debug why a job didn't execute?
A:
- Check job status via persistence provider or dashboard
- Verify execution time has passed
- Check application logs for errors
- Verify function name matches exactly
- Check if job was cancelled or skipped
Q: What happens if I schedule a job with execution time in the past?
A: The job executes immediately (if due) when the scheduler processes it.
Q: Can I update a job that's already running?
A: No. Only jobs with Idle status can be updated. Jobs InProgress cannot be modified.
Q: How do I find all jobs with a specific status?
A: Use the persistence provider (EF Core) to query:
var failedJobs = await _context.Set<TimeTickerEntity>()
.Where(t => t.Status == TickerStatus.Failed)
.ToListAsync();Q: My cron job isn't creating occurrences. Why?
A: Check:
- Cron expression is valid 6-part format
- Expression is parseable (no syntax errors)
- Function name matches
[TickerFunction]attribute - Next occurrence is calculated correctly (check logs)
Getting Help
If you're still experiencing issues:
- Check Documentation: Review relevant sections
- Search Issues: Check GitHub issues for similar problems
- Create Minimal Reproduction: Create a minimal example that reproduces the issue
- Provide Details: Include:
- TickerQ version
- .NET version
- Error messages with full stack traces
- Complete configuration code
- Steps to reproduce
- Application logs
