kgretzky/evilginx2 · error

you can only use time duration types in following order: 'd'

Error message

you can only use time duration types in following order: 'd' > 'h' > 'm' > 's'

What it means

ParseDurationString parses custom duration strings like '5d12h30m' used for lure pause times. It enforces that unit characters appear in strictly descending order 'd' > 'h' > 'm' > 's'; if a unit character's index is not greater than the previous one (e.g. '30m5d' or '5h3h'), this error is returned and parsing stops.

Source

Thrown at core/utils.go:116

					if m_index > last_type_index {
						last_type_index = m_index
						var val int64
						val, err = strconv.ParseInt(s_num, 10, 0)
						if err != nil {
							return
						}
						switch c {
						case 'd':
							days = val
						case 'h':
							hours = val
						case 'm':
							minutes = val
						case 's':
							seconds = val
						}
					} else {
						err = fmt.Errorf("you can only use time duration types in following order: 'd' > 'h' > 'm' > 's'")
						return
					}
				} else {
					err = fmt.Errorf("unknown time duration type: '%s', you can use only 'd', 'h', 'm' or 's'", string(c))
					return
				}
			} else {
				err = fmt.Errorf("time duration value needs to start with a number")
				return
			}
			s_num = ""
		}
	}
	t_dur = time.Duration(days)*24*time.Hour + time.Duration(hours)*time.Hour + time.Duration(minutes)*time.Minute + time.Duration(seconds)*time.Second
	return
}

func GetDurationString(t_now time.Time, t_expire time.Time) (ret string) {

View on GitHub (pinned to 4c0988a1d9)

Solutions

  1. Rewrite the duration with units in order d, h, m, s, e.g. '1d12h30m15s'.
  2. Remove duplicated units by summing them first: '5h3h' → '8h'.
  3. Omit unwanted units entirely rather than reordering: '30m' instead of '30m0d'.

Example fix

// before
ParseDurationString("30s5m")
// after
ParseDurationString("5m30s")
Defensive patterns

Strategy: validation

Validate before calling

var durRe = regexp.MustCompile(`^(?:\d+d)?(?:\d+h)?(?:\d+m)?(?:\d+s)?$`)
if !durRe.MatchString(durStr) {
    return fmt.Errorf("duration %q must use ordered units d>h>m>s, e.g. 1d12h30m", durStr)
}
d, err := core.ParseDurationString(durStr)

Type guard

func isOrderedDuration(s string) bool {
    last := -1
    order := map[rune]int{'d': 0, 'h': 1, 'm': 2, 's': 3}
    for _, c := range s {
        if i, ok := order[c]; ok {
            if i <= last { return false }
            last = i
        } else if c < '0' || c > '9' {
            return false
        }
    }
    return len(s) > 0
}

Try / catch

d, err := core.ParseDurationString(input)
if err != nil {
    if strings.Contains(err.Error(), "following order") {
        log.Printf("units out of order in %q; use d>h>m>s", input)
        return
    }
    return err
}

Prevention

When it happens

Trigger: Passing a duration string whose units are out of order or repeated, e.g. '10s5m', '2h30m15h', '1d12d'.

Common situations: Users familiar with Go's time.ParseDuration writing '1h30s' (allowed by Go, rejected here because 's' after 'h' skips 'm' order is fine but '30s5h' is not), or typos reordering units.

Understand the failure class

Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.

Related errors


AI-assisted analysis of kgretzky/evilginx2@4c0988a1d9 (2026-09-05). Data as JSON: /api/errors/ac6e6797575a3b82. Report an issue: GitHub.