PR 19766 review

rancher/dashboard PR 19766 (codyrancher) at head 405c0e21, reviewed 2026-11-04. It blocks Create and Save when the etcd snapshot Cron Schedule is invalid, for provisioned and imported RKE2/K3s clusters. Fixes issue 19732.

Preview: rancherpr19766r.mf-created-dashboard.ui.rancher.space, built from 405c0e21, backend mf Rancher (v2.16.0-7758e3e-head). Baseline: the shared dashboard-master preview, built 2026-10-26. The only commit touching this code since then changes blur handling in LabeledInput, not the cron path.

Verdict: one small change, then approve

Test it yourself

The login page defaults to OpenLDAP, so click Log in as a local user first, then use admin and RANCHER_PASSWORD.

  1. Create: open PR: Create Custom, etcd, type any name, set Cron Schedule to * * * * * *. Create disables and the warning icon's tooltip explains the format. Open Basics and the etcd tab shows a red icon. Master leaves Create enabled.
  2. Should-fix case: set 0 0 * * 7. Create enables and the hint reads "only on Sunday".
  3. Stored schedules: open the two PR: Edit links (fixtures I created, custom clusters with no nodes). Save is disabled on load for both, but only the first schedule is really broken.
  4. Imported: open PR: Imported test-k3s and try the same values under Day 2 Operations. Don't click Save here: test-k3s is a real cluster entry, and my runs intercepted that write.
Before and after
Master: invalid schedule, Create enabled
master: hint says invalid, Create stays enabled.
PR: invalid schedule, Create disabled, tooltip explains format
PR: Create disabled, and the tooltip explains the format.
PR: etcd tab flagged while Basics is open
PR: etcd tab flagged from another tab.
PR imported cluster: error icons on Day 2 Operations, Automatic Backups and Jump to
PR, imported: icons on the field, the sections and Jump to, with Save disabled.
PR in dark theme with tooltip
PR, dark theme.
Findings
1

Day-of-week 7 passes the new rule, and K3s then takes no snapshots

shell/utils/validators/cron-schedule.js:28 · __tests__/cron-schedule.test.ts:85
Should fix

What I found

isValidCronSchedule passes allowSevenAsSunday: true, and a test row pins 0 0 * * 7 as valid. K3s and RKE2 parse this with robfig/cron/v3, whose day of week is 0-6, so it answers end of range (7) above maximum (6). K3s ignores the error from AddJob, so nothing fails visibly. On master the option only affected a hint. This PR makes it the Save gate.

I started four throwaway K3s v1.33.5 servers with --cluster-init and left them for 4 minutes:

SchedulePR formNodeSnapshotsCron error in logs
* * * * 0-6AllowsReady4–
* * * * 0-7AllowsReady0None
* * * * * * (the issue)BlocksReady0None
@every 1m (card 2)BlocksReady3–
PR form with 0 0 * * 7: Create enabled, hint says only on Sunday
PR preview: 0 0 * * 7. Create is enabled and the hint says "only on Sunday".

Fix

Drop allowSevenAsSunday from isValidCronSchedule and flip the test row. Run against the matrix below, that turns all four 7 rows into blocks and changes nothing else. Adding "day of week is 0-6" to the message would help, because the shared LabeledInput hint keeps its own copy of the check and will still describe 7 as Sunday. I'd leave that hint alone, since other cron forms use it.

Limit: I ran K3s, not RKE2. RKE2 pulls in K3s's etcd package (go.mod), and Rancher passes the schedule through unchanged, but I read those rather than provisioning a node.

2

Working @every and CRON_TZ= schedules now block every Save from the form

shell/utils/validators/cron-schedule.js:20
Your call

What I found

The description lists this as a known regression. I confirmed it and the workaround:

Edit form for a cluster storing @every 6h: Save disabled
PR preview: stored @every 6h, Save disabled.

Options

I don't know how many clusters use these forms, so the size of this is unknown. Issue 13202 (merging the cron validators) is still open and is the longer-term home for it.

3

Noted, no action needed

FYI
Live results
CasemasterPR 19766
Create, Custom
* * * * * *, 60 * * * *, not-a-cron, * * * *, a single spaceCreate enabledDisabled, icon, tab flagged
0 */5 * * *, @daily, 0 0 * * MON-FRI, 0 0 ? * MON, empty, surrounding spacesEnabledEnabled, no flag
Etcd tab while another tab is open, schedule invalidNo flagRed icon, Create disabled
Invalid schedule, then Automatic Backups Disable, then EnableEnabled throughoutEnabled, then disabled again
S3 Enable with no bucketDisabledDisabled, tab flagged
S3 bucket set, re-select EnableDisabled (stuck)Stays enabled
S3 on, invalid schedule, then S3 DisableEnabled, schedule still invalidStays disabled
Bucket and schedule both invalid, fixed one at a timeTracks S3 onlyEnabled only after both
S3 Enable a second time (bucket gone), then Backups Disable, then EnableDisabled, enabled, enabledSame, S3 stays off
Create, Amazon EC2
Invalid schedule, then fixedNot runDisabled + tab error, then enabled
Edit, Custom (real stored values)
Stored * * * * * * on loadSave enabledDisabled, etcd tab flagged
Fix it, break it again, turn backups offEnabled throughoutEnabled, disabled, enabled
Stored @every 6h on loadSave enabledDisabled (card 2)
View mode with stored invalid scheduleNo iconNo icon, no tab flag
Imported K3s, Day 2 Ops
Invalid scheduleSave enabledDisabled, icon on field, section and Jump-to entries
Automatic Backups section collapsed, invalidSave enabledDisabled
Day 2 Ops off, then on, with invalid scheduleEnabledEnabled, then disabled with the error back
S3 no bucket, Day 2 off, then on (remount)Enabled, disabledSame
S3 bucket set, re-select EnableDisabled (stuck)Stays enabled
Stored * * * * * * on load *Save enabledDisabled
Stored @every 6h on load *Save enabledDisabled (card 2)
Stored invalid with backups disabled *EnabledEnabled
Stored S3 with bucket, valid schedule *EnabledEnabled
Stored empty S3 *DisabledSame

* Stored values on imported clusters come from a rewritten /v3/clusters/c-p2bmg GET response, because that cluster's real etcd config is empty. Everything else in the Edit rows is real stored data on the fixtures.

What the validator and K3s each accept
SchedulePR ruleK3s parserAgree?
0 */5 * * *, @daily, 0 0 * * MON-FRI, 0 0 1 JAN,JUN *, */5 * * * *AllowAcceptYes
* * * * * *, 60 * * * *, 0 24 * * *, @reboot, @DAILY, 0 0 L * *, 0 0 * * 1#1BlockRejectYes
0 0 * * 7, 0 0 * * 1-7, 0 0 * * 5-7, 0 0 * * 0,7AllowRejectNo, card 1
@every 6h, @every 1h30m, @every 0s, CRON_TZ=UTC 0 0 * * *, TZ=UTC 0 0 * * *, CRON_TZ=Asia/Tokyo 0 6 * * *BlockAcceptNo, card 2
0 0 ? * ?, ? ? ? ? ?, 0 ? * * *, 0 0 ? ? *, 1,,3 * * * *, 1, * * * *BlockAcceptNo, rare
What else was checked
CheckResult
Validator against parser87 schedules through the PR's logic and robfig/cron/v3 v3.0.1 ParseStandard: 71 agree, 4 wrongly allowed, 12 wrongly blocked.
Unit testsThe touched suites plus pkg/imported pass locally: 11 suites, 290 tests.
Do the tests catch breakage?14 mutations of the validator, composable, rke2.vue and both forms: all 14 fail a test, including re-adding the S3 re-select bug.
CIAll required jobs green on the latest run, e2e and a11y included. Earlier failed Description and Branch Milestone runs were replaced by a green Validate run.
CodeMoved code matches the old copies in both forms, apart from the intended validity change. The moved types have no other importers. The new string is in en-us.yaml, and labels and the tooltip render. No v-html, and any only in test helpers.
ConsoleNo uncaught errors on either preview during the form runs.
Dark themeIcon, tooltip and hint read correctly (body class switched by hand).
SafetyEvery write in the browser runs was intercepted and none changed a cluster. The only real writes are the two fixtures.
Not testedProvisioning a real node with RKE2, an actual Save on the imported form, non-admin roles (no permission logic changed), and non-English locales.

Suggested review (Comment)

In your voice, in the usual shape: short intro, points inline, no code blocks, no preview link. Not posted. I can create it as a pending review with the screenshots attached.

Body

Tested this on a preview against the Create, Edit, Amazon EC2 and imported forms. The block works on all of them and the S3 re-select bug is gone. Two things on the validator, both inline.

Inline on shell/utils/validators/cron-schedule.js:28

allowSevenAsSunday lets 0 0 * * 7 and ranges like 1-7 through, but K3s and RKE2 use robfig/cron, which only takes 0-6 for day of week. K3s also ignores the parse error. On a test server * * * * 0-7 started fine, logged nothing and took no snapshots in 4 minutes, while * * * * 0-6 took 4. So the form still saves the silent failure this PR is blocking, and the hint even says "only on Sunday". Could we drop the option here and flip the 0 0 * * 7 test row? Mentioning 0-6 in the message would help too.

Inline on shell/utils/validators/cron-schedule.js:20

You called out @every 6h and CRON_TZ= in the description. Those work on the cluster (@every 1m took snapshots on my test server), so a healthy cluster can't save anything from the form, version upgrades included, until someone replaces a schedule that isn't broken. Could this accept both forms, so the block only catches schedules that really fail? If you'd rather keep it strict, I think it needs a release note.

Cleanup when the PR merges
Left behindRemove with
Preview dashboard-pr19766 on created-dashboard-2bash preview/cleanup-branch.sh dashboard pr19766
Fixture clusters zz19766-bad-cron and zz19766-every on mf (no nodes)kubectl -n fleet-default delete clusters.provisioning.cattle.io zz19766-bad-cron zz19766-every