kataras/iris · error
invalid offset minutes: %d: %s
Error message
invalid offset minutes: %d: %s
What it means
After parsing the minutes of an unconventional '+HH:MM:SS' offset, adjustForUnconventionalOffset rejects minute values greater than 60. A real timezone offset never has more than 59 minutes (60 is tolerated here as an edge case), so larger values indicate a malformed offset.
Source
Thrown at x/jsonx/iso8601.go:249
if len(offsetParts) != 3 {
return time.Time{}, fmt.Errorf("invalid offset format: %s", offset)
}
hours, err := strconv.Atoi(offsetParts[0])
if err != nil {
return time.Time{}, fmt.Errorf("error parsing offset hours: %s: %w", offset, err)
}
if hours > 24 {
return time.Time{}, fmt.Errorf("invalid offset hours: %d: %s", hours, offset)
}
minutes, err := strconv.Atoi(offsetParts[1])
if err != nil {
return time.Time{}, fmt.Errorf("error parsing offset minutes: %s: %w", offset, err)
}
if minutes > 60 {
return time.Time{}, fmt.Errorf("invalid offset minutes: %d: %s", minutes, offset)
}
seconds, err := strconv.Atoi(offsetParts[2])
if err != nil {
return time.Time{}, fmt.Errorf("error parsing offset seconds: %s: %w", offset, err)
}
if seconds > 60 {
return time.Time{}, fmt.Errorf("invalid offset seconds: %d: %s", seconds, offset)
}
totalOffset := time.Duration(sign) * (time.Duration(hours)*time.Hour + time.Duration(minutes)*time.Minute + time.Duration(seconds)*time.Second)
return t.Add(-totalOffset), nil
}
// UnmarshalJSON parses the "b" into ISO8601 time.
func (t *ISO8601) UnmarshalJSON(b []byte) error {
if len(b) == 0 {View on GitHub (pinned to 7bedaf55a0)
Solutions
- Correct the offset so minutes are within 0–59 (e.g. '+03:59:00').
- Check the producer for field-order or width bugs when composing the offset string.
- Validate offsets at ingestion with a regex before parsing (e.g. ^[+-]\d{1,2}:[0-5]\d:[0-5]\d$).
Example fix
// before
ParseISO8601("2024-01-02T15:04:05+03:90:00") // invalid offset minutes: 90
// after
ParseISO8601("2024-01-02T15:04:05+03:30:00") Defensive patterns
Strategy: validation
Validate before calling
func offsetMinutesInRange(ts string) bool {
i := strings.LastIndexAny(ts, "+-")
if i < 0 { return false }
parts := strings.Split(ts[i+1:], ":")
if len(parts) != 3 { return false }
m, err := strconv.Atoi(parts[1])
return err == nil && m >= 0 && m <= 59
} Try / catch
tt, err := jsonx.ParseISO8601(s)
if err != nil {
if strings.Contains(err.Error(), "invalid offset minutes") {
return fmt.Errorf("timestamp %q has out-of-range offset minutes", s)
}
return err
} Prevention
- Validate offset minutes are 00–59 before parsing.
- Watch for concatenation bugs in custom serializers.
- Prefer standard +HH:MM offsets that avoid this code path.
When it happens
Trigger: ParseISO8601 on a timestamp with an offset like '+03:90:00' — minutes parse as an integer but exceed 60.
Common situations: Buggy serializers concatenating minutes and seconds (e.g. '3059' split wrongly); hand-built offset strings; corrupted data imports.
Related errors
- invalid offset hours: %d: %s
- invalid offset seconds: %d: %s
- ISO8601: invalid timezone format: %s
- invalid offset format: %s
- error parsing offset hours: %s: %w
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/f87a1aa19ba008aa.
Report an issue: GitHub.