junit-team/junit5 · error · ExtensionConfigurationException

Either a valid time zone id or a TimeZoneProvider must be pr

Error message

Either a valid time zone id or a TimeZoneProvider must be provided to DefaultTimeZone

What it means

Thrown as ExtensionConfigurationException by DefaultTimeZoneExtension.validateCorrectConfiguration when @DefaultTimeZone is misconfigured: EITHER both 'value' (zone id) is empty AND timeZoneProvider is the default NullTimeZoneProvider (neither supplied), OR both value and a non-default provider are supplied (both supplied). Exactly one of value= or timeZoneProvider= must be set.

Source

Thrown at junit-jupiter-api/src/main/java/org/junit/jupiter/api/util/DefaultTimeZoneExtension.java:73

				.map(DefaultTimeZoneExtension::createTimeZone);
	}

	private static TimeZone createTimeZone(DefaultTimeZone annotation) {
		validateCorrectConfiguration(annotation);

		if (!annotation.value().isEmpty()) {
			return createTimeZoneFromZoneId(annotation.value());
		}
		else {
			return createTimeZoneFromProvider(annotation.timeZoneProvider());
		}
	}

	private static void validateCorrectConfiguration(DefaultTimeZone annotation) {
		boolean noValue = annotation.value().isEmpty();
		boolean noProvider = annotation.timeZoneProvider() == NullTimeZoneProvider.class;
		if (noValue == noProvider) {
			throw new ExtensionConfigurationException(
				"Either a valid time zone id or a TimeZoneProvider must be provided to "
						+ DefaultTimeZone.class.getSimpleName());
		}
	}

	private static TimeZone createTimeZoneFromZoneId(String timeZoneId) {
		TimeZone configuredTimeZone = TimeZone.getTimeZone(timeZoneId);
		// TimeZone::getTimeZone returns with GMT as fallback if the given ID cannot be understood
		if (configuredTimeZone.equals(TimeZone.getTimeZone("GMT")) && !"GMT".equals(timeZoneId)) {
			throw new ExtensionConfigurationException("""
					@DefaultTimeZone not configured correctly.
					Could not find the specified time zone + '%s'.
					Please use correct identifiers, e.g. "GMT" for Greenwich Mean Time.
					""".formatted(timeZoneId));
		}
		return configuredTimeZone;
	}

View on GitHub (pinned to 956246301e)

Solutions

  1. Set exactly one: @DefaultTimeZone(value = "GMT") OR @DefaultTimeZone(timeZoneProvider = MyProvider.class).
  2. If you do not need a custom time zone at all, remove the @DefaultTimeZone annotation entirely.
  3. Double-check that an IDE-generated annotation stub did not leave both attributes blank.

Example fix

// before
@DefaultTimeZone(value = "GMT", timeZoneProvider = MyTimeZoneProvider.class)
void test() {}

// after — pick one source
@DefaultTimeZone(value = "GMT")
void test() {}
Defensive patterns

Strategy: validation

Validate before calling

DefaultTimeZone tz = testClass.getAnnotation(DefaultTimeZone.class);
boolean hasValue = !tz.value().isEmpty();
boolean hasProvider = tz.timeZoneProvider() != NullTimeZoneProvider.class;
if (hasValue == hasProvider) { // both set or both unset
    throw new IllegalStateException("@DefaultTimeZone requires exactly one of value= or timeZoneProvider=");
}

Prevention

When it happens

Trigger: An empty @DefaultTimeZone() with no attributes; or @DefaultTimeZone(value = "GMT", timeZoneProvider = MyProvider.class) supplying both at once.

Common situations: Forgetting to fill in either attribute; copy-pasting an annotation and adding value= on top of an existing provider=; misunderstanding that the two are mutually exclusive sources of the TimeZone.

Related errors


AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04). Data as JSON: /data/errors/90d177863e6bcac2.json. Report an issue: GitHub.