junit-team/junit5 · error · DateTimeParseException

Timeout duration is not in the expected format

Error message

Timeout duration is not in the expected format (<number> [ns|μs|ms|s|m|h|d])

What it means

Thrown when a timeout duration string supplied to @Timeout (or the junit.jupiter.execution.timeout.* configuration parameters) does not match the expected pattern: a positive integer (starting with 1-9) optionally followed by a unit abbreviation (ns, μs, ms, s, m, h, d). The parser uses a strict regex ([1-9]\d*) so values like '0', '1.5s', '500ms ' with trailing junk, or '-3' all fail. If no unit is given, seconds is assumed.

Solutions

  1. Ensure the duration string is a positive integer (no leading zeros, no decimals) optionally followed by one of: ns, μs, ms, s, m, h, d
  2. If you need microseconds, use the Unicode micro symbol μ (U+00B5), not the ASCII 'u'
  3. If you intended 'no timeout', remove the @Timeout annotation or configuration parameter rather than setting it to 0
  4. For fractional timeouts, round up to the nearest integer and use a smaller unit (e.g., '1500ms' instead of '1.5s')

Example fix

// before
@Timeout(value = 0, unit = TimeUnit.SECONDS)
void myTest() { }

// Or in configuration:
// junit.jupiter.execution.timeout.testmethod.default = 1.5s

// after
@Timeout(value = 5, unit = TimeUnit.SECONDS)
void myTest() { }

// Or via configuration parameter (integer + optional unit):
// junit.jupiter.execution.timeout.testmethod.default = 500ms
Defensive patterns

Strategy: validation

Validate before calling

// Validate timeout string before passing to configuration
import java.util.regex.Pattern;

private static final Pattern TIMEOUT_PATTERN =
    Pattern.compile("([1-9]\\d*) ?((?:[nμm]?s)|m|h|d)?", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);

static boolean isValidTimeout(String value) {
    return value != null && TIMEOUT_PATTERN.matcher(value).matches();
}

// Usage before setting configuration:
String timeout = "500ms";
if (!isValidTimeout(timeout)) {
    throw new IllegalArgumentException("Invalid timeout format: " + timeout);
}

Prevention

When it happens

Trigger: Set junit.jupiter.execution.timeout.testmethod.default to a malformed string like '0', '-1', '1.5', 'abc', or '100x'. Annotate a test with @Timeout(value=0) or pass a duration string containing an unrecognized unit. Using 'us' instead of the Unicode 'μs' microsecond abbreviation also fails because the regex only matches [nμm]?s.

Common situations: Developers commonly hit this when migrating from another timeout library that uses 'us' for microseconds, or when supplying fractional values like '1.5s'. Another frequent case is setting the timeout to '0' expecting 'no timeout', which the regex rejects because it requires [1-9] as the first digit. Copy-pasting timeout values from documentation that uses a different unit abbreviation scheme (e.g., 'sec' or 'min') also triggers it.

Understand the failure class

Related errors


AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11). Data as JSON: /api/errors/42324cf4e227631a. Report an issue: GitHub.

Appendix: source

Thrown at junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutDurationParser.java:58

		"ns", NANOSECONDS, //
		"μs", MICROSECONDS, //
		"ms", MILLISECONDS, //
		"s", SECONDS, //
		"m", MINUTES, //
		"h", HOURS, //
		"d", DAYS //
	);

	TimeoutDuration parse(CharSequence text) throws DateTimeParseException {
		Matcher matcher = PATTERN.matcher(text);
		if (matcher.matches()) {
			long value = Long.parseLong(matcher.group(1));
			String unitAbbreviation = matcher.group(2);
			TimeUnit unit = unitAbbreviation == null ? SECONDS
					: requireNonNull(UNITS_BY_ABBREVIATION.get(unitAbbreviation.toLowerCase(Locale.ENGLISH)));
			return new TimeoutDuration(value, unit);
		}
		throw new DateTimeParseException("Timeout duration is not in the expected format (<number> [ns|μs|ms|s|m|h|d])",
			text, 0);
	}

}

View on GitHub (pinned to f070c699a0)