Netflix/chaosmonkey · error
%d is not in cron range(0-23)
Error message
%d is not in cron range(0-23)
What it means
Sentinel-style validation error from the helper calculateDefaultCronRunHour, which computes the default cron hour as startHour minus cronBeforeStartHour. It fires when the caller (CronExpression) passes a startHour outside the allowed clock bounds (below clockStartHour or above clockEndHour, nominally 0-23); the faulty input is the out-of-range startHour integer.
Source
Thrown at config/monkey.go:475
if err != nil {
return "", err
}
return fmt.Sprintf(defaultCron, runAtHour), nil
}
switch cron := cron.(type) {
default:
return "", fmt.Errorf("%s: unexpected type %T", param.CronExpression, cron)
case string:
return cron, nil
}
}
// calculates the default cron run hour based on startHour.
// The default cron starts "cronBeforeStartHour" hours
// before "startHour"
func calculateDefaultCronRunHour(startHour int) (int, error) {
if (startHour < clockStartHour) || (startHour > clockEndHour) {
return -1, errors.Errorf("%d is not in cron range(0-23)", startHour)
}
runAtHour := startHour - cronBeforeStartHour
if runAtHour < 0 {
// assuming a 24 hour clock system(0 - 23), -ve values means going back to previous day
// e.g. if start hour is 0 (midnight), the "cronTime" time should be 22 hours
// on the previous day.
return hoursInClock + runAtHour, nil
}
return runAtHour, nil
}
// ScheduleCronPath returns the path to which
// main chaosmonkey crontab is located
func (m *Monkey) ScheduleCronPath() string {
return m.v.GetString(param.ScheduleCronPath)
}
// SchedulePath returns the path to which mainView on GitHub (pinned to eaa28fb761)
Solutions
- Set the start hour to a valid 0-23 (24-hour clock) value in config
- Validate startHour at config load time before calling CronExpression
- Check for clock conventions mixing 1-24 or 12-hour formats
Example fix
// before startHour = 25 // after startHour = 1
Defensive patterns
Strategy: validation
Validate before calling
func validHour(h int) bool { return h >= 0 && h <= 23 }
if !validHour(cfg.StartHour()) {
return fmt.Errorf("startHour %d must be 0-23", cfg.StartHour())
} Try / catch
_, err := calculateDefaultCronRunHour(startHour)
if err != nil {
log.Printf("invalid start hour %d, defaulting to 0", startHour)
startHour = 0
} Prevention
- Validate startHour at config load time
- Use the 24-hour clock convention (0-23) in docs and schema
- Add range assertions in config tests
- Reject out-of-range hours before scheduling
When it happens
Trigger: CronExpression() is called with a configured start hour below clockStartHour (0) or above clockEndHour (23), e.g. startHour = 24 or a negative value.
Common situations: Config typo like startHour=2400 or 25, off-by-one from 1-12 or 1-24 style conventions, bad values from an upstream config generator.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- non-string in %v
- FATAL: no spinnaker endpoint specified in config
- failed to populate schedule: %v
- deploySchedule: could not retrieve local timezone: %v
- failed to read config file
AI-assisted analysis of Netflix/chaosmonkey@eaa28fb761 (2026-09-03).
Data as JSON: /api/errors/fa65b06be65e26e9.
Report an issue: GitHub.