kataras/iris · error

invalid duration

Error message

invalid duration

What it means

jsonx.Duration.UnmarshalJSON returns 'invalid duration' when the JSON token cannot be interpreted as a duration number. The type accepts JSON numbers (and strings per the switch); any other JSON kind (bool, object, array, null) falls to the default branch and errors. It guards a custom time.Duration wrapper used in config/JSON decoding.

Source

Thrown at x/jsonx/duration.go:35

func (d *Duration) UnmarshalJSON(b []byte) error {
	var v any
	if err := json.Unmarshal(b, &v); err != nil {
		return err
	}
	switch value := v.(type) {
	case float64:
		*d = Duration(value)
		return nil
	case string:
		v, err := time.ParseDuration(value)
		if err != nil {
			return err
		}
		*d = Duration(v)
		return nil
	default:
		return errors.New("invalid duration")
	}
}

func (d Duration) ToDuration() time.Duration {
	return time.Duration(d)
}

func (d Duration) Value() (driver.Value, error) {
	return int64(d), nil
}

// Set sets the value of duration in nanoseconds.
func (d *Duration) Set(v float64) {
	if math.IsNaN(v) {
		return
	}

	*d = Duration(v)

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Supply the field as a number (nanoseconds) or a supported string form
  2. Fix the JSON/config value's type to match the Duration field
  3. Check with json.Valid or a schema validator before unmarshalling

Example fix

// before
{"timeout": {"seconds": 5}}
// after
{"timeout": "5s"}
Defensive patterns

Strategy: validation

Validate before calling

var probe map[string]json.RawMessage
if err := json.Unmarshal(raw, &probe); err != nil { return err }
if v, ok := probe["timeout"]; ok && (v[0] == '{' || v[0] == '[' || v[0] == 't') {
    return fmt.Errorf("timeout must be number or duration string")
}

Type guard

func isInvalidDuration(err error) bool { return err != nil && strings.Contains(err.Error(), "invalid duration") }

Try / catch

if err := json.Unmarshal(raw, &cfg); err != nil {
    if strings.Contains(err.Error(), "invalid duration") {
        return fmt.Errorf("config field %q: use e.g. \"5s\" or 5000000000", "timeout")
    }
    return err
}

Prevention

When it happens

Trigger: Unmarshalling JSON where a Duration field receives a non-number, non-string token, e.g. {"timeout": true} or {"timeout": {}} instead of {"timeout": 5} or {"timeout": "5s"}.

Common situations: Typo or wrong unit in a config file that declares a duration field; API payload schema drift where a duration field became an object; forgetting that JSON has no native duration type.

Related errors


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/81d407593c9dc661. Report an issue: GitHub.