junit-team/junit5 · error · ExtensionConfigurationException

@DefaultLocale can only be used with language tag if provide

Error message

@DefaultLocale can only be used with language tag if provider is not set

What it means

Thrown as ExtensionConfigurationException by DefaultLocaleExtension.createFromParts when @DefaultLocale is configured with the language attribute (parts-based mode) AND a non-default localeProvider class. Note: the message text mentions 'language tag' but the code path is the parts-based mode (language=...); the message wording is misleading — the real rule is that the provider attribute is mutually exclusive with all parts-based attributes.

Source

Thrown at junit-jupiter-api/src/main/java/org/junit/jupiter/api/util/DefaultLocaleExtension.java:81

			return createFromParts(annotation);
		}
		else {
			return getFromProvider(annotation);
		}
	}

	private static Locale createFromLanguageTag(DefaultLocale annotation) {
		if (!annotation.language().isEmpty() || !annotation.country().isEmpty() || !annotation.variant().isEmpty()
				|| annotation.localeProvider() != NullLocaleProvider.class) {
			throw new ExtensionConfigurationException(
				"@DefaultLocale can only be used with language tag if language, country, variant and provider are not set");
		}
		return Locale.forLanguageTag(annotation.value());
	}

	private static Locale createFromParts(DefaultLocale annotation) {
		if (annotation.localeProvider() != NullLocaleProvider.class)
			throw new ExtensionConfigurationException(
				"@DefaultLocale can only be used with language tag if provider is not set");
		String language = annotation.language();
		String country = annotation.country();
		String variant = annotation.variant();
		if (!language.isEmpty() && !country.isEmpty() && !variant.isEmpty()) {
			return JupiterLocaleUtils.createLocale(language, country, variant);
		}
		else if (!language.isEmpty() && !country.isEmpty()) {
			return JupiterLocaleUtils.createLocale(language, country);
		}
		else if (!language.isEmpty() && variant.isEmpty()) {
			return JupiterLocaleUtils.createLocale(language);
		}
		else {
			throw new ExtensionConfigurationException(
				"@DefaultLocale not configured correctly. When not using a language tag, specify either"
						+ " language, or language and country, or language and country and variant.");
		}

View on GitHub (pinned to 956246301e)

Solutions

  1. If you want a provider-supplied Locale, remove language= (and country=, variant=) and set only localeProvider=.
  2. If you want parts-based Locale construction, remove the localeProvider= attribute (leave it as the default NullLocaleProvider).

Example fix

// before
@DefaultLocale(language = "en", localeProvider = MyLocaleProvider.class)
void test() {}

// after — provider-only mode
@DefaultLocale(localeProvider = MyLocaleProvider.class)
void test() {}
Defensive patterns

Strategy: validation

Validate before calling

DefaultLocale d = testClass.getAnnotation(DefaultLocale.class);
boolean partsSet = !d.language().isEmpty() || !d.country().isEmpty() || !d.variant().isEmpty();
boolean providerSet = d.localeProvider() != NullLocaleProvider.class;
if (partsSet && providerSet) {
    throw new IllegalStateException("@DefaultLocale parts and provider are mutually exclusive");
}

Prevention

When it happens

Trigger: Annotating a test with @DefaultLocale(language = "en", localeProvider = MyProvider.class). country= and variant= are irrelevant to this branch; only the combination of a set language and a non-NullLocaleProvider triggers it.

Common situations: Migrating from parts-based configuration to a provider and forgetting to clear the language= attribute; misunderstanding that localeProvider is a third mutually-exclusive mode.

Related errors


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