temporalio/temporal · error
conflicting timezone names
Error message
conflicting timezone names
What it means
errConflictingTimezoneNames is returned by canonicalizeSpec when a calendar/cron spec carries two different timezone designations — for example a TZ= prefix on a cron string plus a TimeZoneName on the structured spec, or different IANA names in nested specs. The scheduler cannot pick a single zone deterministically, so parsing fails.
Source
Thrown at service/worker/scheduler/calendar.go:54
// max length of one calendar comment field
maxCommentLen = 200
)
const (
// Modes for parsing range strings: all modes accept decimal integers
parseModeInt parseMode = iota
// parseModeYear is like parseModeInt but returns an empty range for the default
parseModeYear
// parseModeMonth also accepts month name prefixes (at least three letters)
parseModeMonth
// parseModeDow also accepts day-of-week prefixes (at least two letters)
parseModeDow
)
var (
errOutOfRange = errors.New("out of range")
errConflictingTimezoneNames = errors.New("conflicting timezone names")
monthStrings = []string{
"january",
"february",
"march",
"april",
"may",
"june",
"july",
"august",
"september",
"october",
"november",
"december",
}
dowStrings = []string{
"sunday",View on GitHub (pinned to bde624efd1)
Solutions
- Remove one of the two timezone declarations — keep either the TZ=/CRON_TZ= prefix or the spec's timezone field, not both.
- If both are set, make them identical is not allowed; clear the legacy field and re-apply the update.
- Use temporal schedule update describe output to confirm which timezone the schedule currently uses before editing.
- Standardize on one timezone mechanism (usually the structured spec's timezone name) across automation tooling.
Example fix
// before cron := "TZ=America/New_York 0 9 * * *" spec.TimeZoneName = "Europe/London" // conflict // after cron := "0 9 * * *" spec.TimeZoneName = "America/New_York"
Defensive patterns
Strategy: validation
Validate before calling
func checkSingleTimezone(cron string, tzName string) error {
hasTZPrefix := strings.HasPrefix(cron, "TZ=") || strings.HasPrefix(cron, "CRON_TZ=")
if hasTZPrefix && tzName != "" {
return errors.New("spec sets timezone in both cron prefix and spec field")
}
return nil
} Try / catch
if err != nil && strings.Contains(err.Error(), "conflicting timezone names") {
// clear one timezone source and re-apply the schedule update
} Prevention
- Standardize on one timezone mechanism (structured spec TimeZoneName) across tooling.
- When migrating cron strings to structured specs, strip TZ=/CRON_TZ= prefixes.
- Run `temporal schedule describe` before updates to see the current timezone source.
When it happens
Trigger: Updating a schedule while supplying a cron string with TZ=/CRON_TZ= AND setting a separate timezone field on the structured spec to a different name; programmatic schedule updates that copy an old timezone field while changing the cron prefix.
Common situations: Migrating from cron-string schedules to structured CalendarSpec and leaving both timezone sources set; tools that append CRON_TZ without checking existing spec timezone; hand-edited schedule configs after a datacenter/region change.
Related errors
- CronString has time zone but missing fields
- out of range
- ${errs}
- CronString does not have 5-7 fields
- CronString does not have interval after @every
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/196041c5cf8e64e8.
Report an issue: GitHub.