XTLS/Xray-core · error

invalid duration: %v

Error message

invalid duration: %v

What it means

Duration.UnmarshalJSON accepts only a JSON string parseable by time.ParseDuration (e.g. "300ms", "1m30s"). The default branch fires when the JSON value is any other type — a bare number, boolean, null, array, or object — and reports the received Go value with %v.

Source

Thrown at infra/conf/cfgcommon/duration/duration.go:33

}

// UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON
func (d *Duration) UnmarshalJSON(b []byte) error {
	var v interface{}
	if err := json.Unmarshal(b, &v); err != nil {
		return err
	}
	switch value := v.(type) {
	case string:
		var err error
		dr, err := time.ParseDuration(value)
		if err != nil {
			return err
		}
		*d = Duration(dr)
		return nil
	default:
		return fmt.Errorf("invalid duration: %v", v)
	}
}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Find the field named in the surrounding parse error and quote its value as a duration string with an explicit unit
  2. Use supported units: ns, us/µs, ms, s, m, h (composable, e.g. "1m30s")
  3. Do not use bare numbers — "5" alone is invalid even quoted
  4. Lint JSON configs for numeric values in known duration fields before deploy

Example fix

// before
"healthCheck": { "interval": 5, "idleTimeout": 300 }

// after
"healthCheck": { "interval": "5s", "idleTimeout": "300s" }
Defensive patterns

Strategy: type-guard

Type guard

// JSON Schema-style guard for duration fields: must be a string with a unit
const durationRe = /^\d+(ns|us|µs|ms|s|m|h)+$/;
function isDurationString(v) {
  return typeof v === "string" && durationRe.test(v);
}
// assert isDurationString(cfg.healthCheck.interval) before writing config

Prevention

When it happens

Trigger: Writing "idleTimeout": 300 or "interval": 5 instead of "300s"/"5m" anywhere a cfgcommon.Duration field is configured (health checks, policy buffer sizes/timeouts, transport keep-alive intervals, etc.).

Common situations: Muscle memory from configs where numeric seconds are accepted; JSON generators emitting numbers; migrating configs from tools that allow bare integers for durations.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/9aaac545d308d582. Report an issue: GitHub.