| What you write | On the cluster | master | Round one405c0e2 | Nowe11c386 |
|---|
| Accepted everywhere |
| Five numeric fields 0 */5 * * *0 */12 * * ** * * * *0 0 * * 00 0 * * 6
| Snapshots runK3s and RKE2 | ✅ Saves | ✅ Saves | ✅ Saveshint: reads fine |
| Steps, ranges and lists */5 * * * *0/5 * * * *5/15 * * * *1-5/2 * * * *1,2,3 * * * **/60 * * * *0 0 * * */7
| Snapshots runK3s for some, parser for the rest | ✅ Saves | ✅ Saves | ✅ Saveshint: reads fine |
| Day and month names, any case 0 0 * * MON0 0 * * mon0 0 * * Mon0 0 * * MON-FRI0 0 * * mon-fri0 0 * * MON,WED,FRI0 0 * * SUN0 0 * JAN *0 0 * jan *0 0 * JAN-MAR *0 0 1 JAN,JUN *
| Snapshots runK3s for some, parser for the rest | ✅ Saves | ✅ Saves | ✅ Saveshint: reads fine |
| Shortcuts @yearly@annually@monthly@weekly@daily@midnight@hourly
@daily, @midnight and @hourly fired once each at a real local midnight. @weekly, @monthly, @yearly and @annually can't fire in a short test. In the parser they match their numeric forms for 20 years.
| Snapshots runK3s and RKE2 for some, parser for the rest | ✅ Saves | ✅ Saves | ✅ Saveshint: reads fine |
? in one day field0 0 ? * MON0 0 1 * ?
| Snapshots runK3s for some, parser for the rest | ✅ Saves | ✅ Saves | ✅ Saveshint: reads fine |
| Leading zeros and extra spaces 00 00 * * *007 * * * * 0 0 * * *0 0 * * * 0 0 * * *
| Snapshots runK3s for some, parser for the rest | ✅ Saves | ✅ Saves | ✅ Saveshint: reads fine |
| A date that never comes (Feb 31) 0 0 31 2 *
Blocking it would need a calendar check. The server runs normally and just never takes a snapshot. | Parses, never firesParser; K3s stays up | ➖ Saves | ➖ Saves | ➖ Saveshint: reads fine |
| Empty field (empty)
Rancher sends nothing, so the cluster keeps its default schedule. | Keeps its defaultRancher source | ➖ Saves | ➖ Saves | ➖ Saveshint: no complaint |
| Where master, round one and this round differ |
| Day of week 7, alone or in a range 0 0 * * 70 0 * * 1-70 0 * * 5-70 0 * * 0,7
Your first comment, fixed. The grey hint still describes it as Sunday. | No snapshots, no errorK3s and RKE2 | ❌ Saves | ❌ Saves | ✅ Blockshint: reads fine |
@every with a duration@every 6h@every 1h30m
Your second comment, fixed. The grey hint still says Invalid, as on master. | Snapshots runK3s and RKE2 | ✅ Saves | ❌ Blocks | ✅ Saveshint: Invalid |
| Timezone prefix with UTC CRON_TZ=UTC 0 0 * * *TZ=UTC 0 0 * * *CRON_TZ=UTC @dailyTZ=UTC @every 6h
Your second comment, fixed. UTC works with or without timezone data on the node. | Snapshots runK3s and RKE2 | ✅ Saves | ❌ Blocks | ✅ Saveshint: Invalid |
| Timezone prefix with a named zone CRON_TZ=Asia/Tokyo 0 6 * * *
With timezone data on the node it fires, at the right local time. Without it there are no snapshots and no error, on both K3s and RKE2. The form can't see the node. | Runs only if the node has timezone dataK3s and RKE2 | ➖ Saves | ➖ Blocks | ➖ Saveshint: Invalid |
| Unknown timezone name TZ=Nope 0 0 * * *
The one wrong row left. The code comment says the zone isn't checked, for the reason in the row above. On K3s: node Ready, 0 snapshots, no error. | No snapshots, no errorK3s | ❌ Saves | ✅ Blocks | ❌ Saveshint: Invalid |
@every too long to parse@every 999999999h
Now blocked, at the parser's real limit: @every 2562047h saves and @every 2562048h blocks. On K3s this round: 0 snapshots, no error. | No snapshots, no errorK3s | ❌ Saves | ✅ Blocks | ✅ Blockshint: Invalid |
@every with zero or under a second@every 0s@every 500ms
About 70 snapshots in 4 minutes on K3s. Valid, but rarely what anyone means. The PR now behaves like master here. | A snapshot every few secondsK3s | ➖ Saves | ➖ Blocks | ➖ Saveshint: Invalid |
@every with a negative duration@every -1h
Same burst of snapshots. The PR has a test row that blocks it. That differs from the parser and is the better result. | A snapshot every few secondsK3s | ➖ Saves | ➖ Blocks | ➖ Blockshint: Invalid |
? in both day fields or in minute or hour0 0 ? * ?? ? ? ? ?0 ? * * *0 0 ? ? *
Now saves. These fired on K3s in round one. | Snapshots runK3s | ✅ Saves | ❌ Blocks | ✅ Saveshint: Invalid |
| Stray commas 1,,3 * * * *1, * * * *
Now saves. These fired on K3s in round one. | Snapshots runK3s | ✅ Saves | ❌ Blocks | ✅ Saveshint: Invalid |
| Other odd forms that happen to parse +1 * * * **-5 * * * *?/2 * * * *@every .5h@every 1.hTZ=UTC @daily
Now saves, so I ran them this round: *-5, ?/2, a leading + and a .5 duration took snapshots on K3s and RKE2. A 1. duration and a trailing space after a timezone did on K3s. | Snapshots runK3s and RKE2 for some, parser for the rest | ✅ Saves | ❌ Blocks | ✅ Saveshint: Invalid |
| Crash: master saves these, and the K3s or RKE2 server stops at startup |
| Timezone with nothing after it, or a tab instead of the space TZ=UTCCRON_TZ=UTCTZ=UTC<tab>@daily
The parser panics rather than returning an error, and the server exits. In the generated comparison 10,449 schedules panic the parser, and the PR saves none of them. | Server stops at startupK3s and RKE2 | ❌ Saves | ✅ Blocks | ✅ Blockshint: Invalid |
| Broken: master saves these, and the cluster takes no snapshots |
| Six or four fields * * * * * ** * * *0 0 * * * 2026
The issue's case. | No snapshots, no errorK3s for some, parser for the rest | ❌ Saves | ✅ Blocks | ✅ Blockshint: Invalid |
| Out of range 60 * * * *0 24 * * *0 0 0 * *0 0 32 * *0 0 * 0 *0 0 * 13 *0 0 * * 8*/0 * * * *-1 * * * *
| No snapshots, no errorK3s for some, parser for the rest | ❌ Saves | ✅ Blocks | ✅ Blockshint: Invalid |
| Backward ranges 5-1 * * * *0 22-2 * * *0 0 * * FRI-MON
| No snapshots, no errorParser only | ❌ Saves | ✅ Blocks | ✅ Blockshint: Invalid |
| Other cron dialects 0 0 L * *0 0 * * 5L0 0 * * 1#10 0 15W * *H * * * *@reboot
| No snapshots, no errorK3s for some, parser for the rest | ❌ Saves | ✅ Blocks | ✅ Blockshint: Invalid |
| Not numbers 1.5 * * * *0x10 * * * *
| No snapshots, no errorParser only | ❌ Saves | ✅ Blocks | ✅ Blockshint: Invalid |
Malformed @every@every@every 90@every 1d@every 6h
| No snapshots, no errorK3s for some, parser for the rest | ❌ Saves | ✅ Blocks | ✅ Blockshint: Invalid |
| Timezone prefix on a broken schedule CRON_TZ=UTC * * * * * *
| No snapshots, no errorParser only | ❌ Saves | ✅ Blocks | ✅ Blockshint: Invalid |
| Shortcut in the wrong case, or made up @DAILY@Daily@foo
| No snapshots, no errorParser only | ❌ Saves | ✅ Blocks | ✅ Blockshint: Invalid |
| Not a schedule, or only spaces not-a-crondaily(spaces)(spaces)
| No snapshots, no errorParser only | ❌ Saves | ✅ Blocks | ✅ Blockshint: Invalid |