| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| README.md | 2026-03-29 | 10.2 kB | |
| v3.17.0 source code.tar.gz | 2026-03-29 | 5.9 MB | |
| v3.17.0 source code.zip | 2026-03-29 | 6.5 MB | |
| Totals: 3 Items | 12.4 MB | 0 | |
This is a major bug-fix release with 40+ fixes spanning trigger state management, clustering reliability, DST handling, misfire accuracy, and scheduler lifecycle. An optional database schema migration improves misfire handling.
Highlights
Optional database migration: MISFIRE_ORIG_FIRE_TIME column
A new optional column MISFIRE_ORIG_FIRE_TIME on QRTZ_TRIGGERS enables correct ScheduledFireTimeUtc for misfired triggers when using "fire now" misfire policies. Without it, ScheduledFireTimeUtc equals FireTimeUtc for misfired triggers (the pre-existing behavior). RAMJobStore does not require this migration.
Migration script: database/schema_30_add_misfire_orig_fire_time.sql (github.com) (covers SQL Server, PostgreSQL, MySQL, SQLite, Oracle, Firebird)
Clustering and concurrency fixes
- Fix
DisallowConcurrentExecutionjobs running simultaneously in cluster (#2697) - Fix false cluster recovery causing
DisallowConcurrentExecutionviolation (#2915) - Fix triggers stuck in BLOCKED state for
DisallowConcurrentExecutionjobs (#2822) - Fix
FIRED_TRIGGERSnot cleaned up on job deletion mid-execution (#1696) - Handle transient database exceptions (deadlocks) with automatic retry (#2883, [#2952])
- Fix PostgreSQL transaction abort error on lock contention (#2884)
- Fix SQLite "database is locked" errors with dedicated semaphore (#2323)
- Add MySQL FORCE INDEX hints for slow trigger acquisition queries (#547)
Trigger state and fire time accuracy
- Fix
GetTriggerStatereturning Complete instead of Blocked for executing triggers (#2255) - Fix
RAMJobStore.TriggersFiredskipping triggers causing wrong trigger/job execution (#1386) - Fix
ScheduledFireTimeUtcreturning wrong value after misfire (#2899) - Fix
PreviousFireTimeUtcreset to null on restart withOverWriteExistingData=true(#1834) - Fix
SimpleTriggerfirst fire time wrong when created long before scheduling (#2455) - Fix
CronTriggerdouble-firing when rescheduled with oldStartTimeUtc(#2909) - Fix recovery trigger missing original
JobData(#2083) - Fix misfired blocked triggers not being deleted from database (#1646)
- Fix
DoNothingmisfire policy skipping fire times within threshold (#2912)
DST and time handling
- Fix
DailyTimeIntervalTriggerextra fire during DST fall-back (#2917) - Fix
DailyTimeIntervalTriggermutatingStartTimeUtcduring fire time computation (#2906) - Fix
DailyTimeIntervalTriggerRepeatCountto apply per day (#1633) - Fix scheduler thread stuck after system clock jumps backward (#1508)
- Fix
ComputeFireTimesBetweenmodifying trigger StartTimeUtc (#2722)
Scheduler lifecycle and threading
- Fix scheduler hang on shutdown: replace
Monitor.Waitwith asyncSemaphoreSlim(#2877) - Fix shutdown deadlock (#2830)
- Release acquired triggers on shutdown instead of leaking them (#2881)
- Fix
DedicatedThreadPoolthreads leaking on scheduler shutdown (#1357) - Use dedicated thread for scheduler loop to prevent missed triggers under high CPU (#781)
Job execution
- Fix
RefireImmediatelywithJobChainingJobListenerfiring chain prematurely (#663) - Fix
AsyncLocalflow fromIJobFactory.NewJobtoIJob.Execute(#1528) - Add
IJobDetailproperty toJobExecutionException(#1442)
API and configuration
- Fix
idleWaitTimeof zero silently ignored instead of throwing (#1394) - Fix
AddJob/AddTriggerambiguous references without removing overloads (#2795) - Fix
PauseJobs/ResumeJobinteraction bug in RAMJobStore (#761) - Fix
RemoteSchedulerignoring localquartz.scheduler.instanceName(#313) - Restore DB trigger fields for custom (blob) triggers (#2949)
Dashboard
- Fix dashboard CSS 404 in API-only projects (#2886)
What's Changed
- Add IJobDetail property to JobExecutionException by @lahma in https://github.com/quartznet/quartznet/pull/2869
- Fix ComputeFireTimesBetween modifying trigger StartTimeUtc by @lahma in https://github.com/quartznet/quartznet/pull/2870
- Convert integration tests to use Testcontainers.NET by @lahma in https://github.com/quartznet/quartznet/pull/2873
- docs: document RequiresAspNetWebAssets for API-only apps (.NET 10+) by @lahma in https://github.com/quartznet/quartznet/pull/2875
- Fix DoCheckin lock returner warning and ReferenceEquals comparisons by @lahma in https://github.com/quartznet/quartznet/pull/2876
- Fix scheduler hang on shutdown: replace Monitor.Wait with async SemaphoreSlim by @lahma in https://github.com/quartznet/quartznet/pull/2877
- Release acquired triggers on shutdown instead of leaking them by @lahma in https://github.com/quartznet/quartznet/pull/2881
- Port: Handle transient database exceptions with automatic retry (3.x) by @lahma in https://github.com/quartznet/quartznet/pull/2883
- Port PostgreSQL transaction abort fix to 3.x (#2829) by @lahma in https://github.com/quartznet/quartznet/pull/2884
- Port DST fall-back infinite trigger fix to 3.x (#2865) by @lahma in https://github.com/quartznet/quartznet/pull/2885
- Fix dashboard CSS 404 in API-only projects (#2886) by @lahma in https://github.com/quartznet/quartznet/pull/2887
- Port shutdown deadlock fix to 3.x (#2830) by @lahma in https://github.com/quartznet/quartznet/pull/2889
- Use dedicated thread for scheduler loop to prevent missed triggers under high CPU (#781) by @lahma in https://github.com/quartznet/quartznet/pull/2895
- Fix triggers stuck in BLOCKED state for DisallowConcurrentExecution jobs by @Copilot in https://github.com/quartznet/quartznet/pull/2822
- Split integration tests into per-database CI workflows by @lahma in https://github.com/quartznet/quartznet/pull/2900
- Fix ScheduledFireTimeUtc returning wrong value after misfire by @lahma in https://github.com/quartznet/quartznet/pull/2899
- Remove docker folder and docker-compose.yml by @lahma in https://github.com/quartznet/quartznet/pull/2904
- Fix recovery trigger missing original JobData (#2083) by @lahma in https://github.com/quartznet/quartznet/pull/2905
- Fix CronTrigger double-firing when rescheduled with old StartTimeUtc by @lahma in https://github.com/quartznet/quartznet/pull/2909
- Fix DailyTimeIntervalTrigger mutating StartTimeUtc during fire time computation by @lahma in https://github.com/quartznet/quartznet/pull/2906
- Fix DisallowConcurrentExecution jobs running simultaneously in cluster by @lahma in https://github.com/quartznet/quartznet/pull/2908
- Fix DoNothing misfire policy skipping fire times within threshold by @lahma in https://github.com/quartznet/quartznet/pull/2912
- Fix false cluster recovery causing DisallowConcurrentExecution violation by @lahma in https://github.com/quartznet/quartznet/pull/2915
- Fix DailyTimeIntervalTrigger RepeatCount to apply per day (#1633) by @lahma in https://github.com/quartznet/quartznet/pull/2918
- Add DST spring-forward tests for daily, monthly, and EU timezone intervals by @lahma in https://github.com/quartznet/quartznet/pull/2919
- Fix DailyTimeIntervalTrigger extra fire during DST fall-back by @lahma in https://github.com/quartznet/quartznet/pull/2917
- Fix SQLite database is locked errors (#2323) by @lahma in https://github.com/quartznet/quartznet/pull/2923
- Fix PauseJobs/ResumeJob interaction bug in RAMJobStore by @lahma in https://github.com/quartznet/quartznet/pull/2893
- Add MySQL FORCE INDEX hints for slow trigger queries by @lahma in https://github.com/quartznet/quartznet/pull/2894
- Fix misfired blocked triggers not being deleted from database by @Copilot in https://github.com/quartznet/quartznet/pull/2820
- Fix AddJob/AddTrigger ambiguous references without removing overloads (#2795) by @lahma in https://github.com/quartznet/quartznet/pull/2925
- Add CronExpression DST regression tests (#2156) by @lahma in https://github.com/quartznet/quartznet/pull/2927
- Fix scheduler thread stuck after system clock jumps backward (#1508) by @lahma in https://github.com/quartznet/quartznet/pull/2929
- Fix AsyncLocal flow from IJobFactory.NewJob to IJob.Execute (#1528) by @lahma in https://github.com/quartznet/quartznet/pull/2930
- Fix RAMJobStore.TriggersFired skipping triggers causing wrong job execution (#1386) by @lahma in https://github.com/quartznet/quartznet/pull/2933
- Enable NUnit parallel test fixture execution by @lahma in https://github.com/quartznet/quartznet/pull/2936
- Fix GetTriggerState returning Complete instead of Blocked for executing triggers (#2255) by @lahma in https://github.com/quartznet/quartznet/pull/2935
- Fix unit tests failing on DST transition days by @lahma in https://github.com/quartznet/quartznet/pull/2941
- Fix RefireImmediately with JobChainingJobListener firing chain prematurely (#663) by @lahma in https://github.com/quartznet/quartznet/pull/2940
- Fix FIRED_TRIGGERS not cleaned up on job deletion mid-execution (#1696) by @lahma in https://github.com/quartznet/quartznet/pull/2945
- Restore DB trigger fields for custom (blob) triggers by @lahma in https://github.com/quartznet/quartznet/pull/2949
- Backport trigger type switch test coverage to 3.x by @lahma in https://github.com/quartznet/quartznet/pull/2948
- Fix idleWaitTime of zero silently ignored instead of throwing (#1394) by @lahma in https://github.com/quartznet/quartznet/pull/2950
- Fix RemoteScheduler ignoring local quartz.scheduler.instanceName (#313) by @lahma in https://github.com/quartznet/quartznet/pull/2953
- Fix DedicatedThreadPool threads leaking on scheduler shutdown by @lahma in https://github.com/quartznet/quartznet/pull/2954
- Fix TriggersFired not retrying transient database errors by @lahma in https://github.com/quartznet/quartznet/pull/2952
- Fix PreviousFireTimeUtc reset to null on restart with OverWriteExistingData (#1834) by @lahma in https://github.com/quartznet/quartznet/pull/2957
- Fix SimpleTrigger first fire time when created before scheduling (#2455) by @lahma in https://github.com/quartznet/quartznet/pull/2958
Full Changelog: https://github.com/quartznet/quartznet/compare/v3.16.1...v3.17.0