spring-projects/spring-security · error · BeanDefinitionStoreException

Use of a properties file and user elements are mutually excl

Error message

Use of a properties file and user elements are mutually exclusive

What it means

UserServiceBeanDefinitionParser parses the <security:user-service> XML element into an InMemoryUserDetailsManager. A user service may be populated either from a properties resource (the 'properties' attribute) or from inline <user> child elements, but not both at once; supplying both would make the user source ambiguous, so parsing aborts with this BeanDefinitionStoreException at context startup.

Source

Thrown at config/src/main/java/org/springframework/security/config/authentication/UserServiceBeanDefinitionParser.java:69

	static final String ATT_PROPERTIES = "properties";
	static final String ATT_DISABLED = "disabled";
	static final String ATT_LOCKED = "locked";

	private SecureRandom random;

	@Override
	protected String getBeanClassName(Element element) {
		return InMemoryUserDetailsManager.class.getName();
	}

	@Override
	@SuppressWarnings("unchecked")
	protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
		String userProperties = element.getAttribute(ATT_PROPERTIES);
		List<Element> userElts = DomUtils.getChildElementsByTagName(element, ELT_USER);
		if (StringUtils.hasText(userProperties)) {
			if (!CollectionUtils.isEmpty(userElts)) {
				throw new BeanDefinitionStoreException(
						"Use of a properties file and user elements are mutually exclusive");
			}
			BeanDefinition bd = new RootBeanDefinition(PropertiesFactoryBean.class);
			bd.getPropertyValues().addPropertyValue("location", userProperties);
			builder.addConstructorArgValue(bd);
			return;
		}
		if (CollectionUtils.isEmpty(userElts)) {
			throw new BeanDefinitionStoreException("You must supply user definitions, either with <" + ELT_USER
					+ "> child elements or a " + "properties file (using the '" + ATT_PROPERTIES + "' attribute)");
		}
		ManagedList<BeanDefinition> users = new ManagedList<>();
		for (Object elt : userElts) {
			Element userElt = (Element) elt;
			String userName = userElt.getAttribute(ATT_NAME);
			String password = userElt.getAttribute(ATT_PASSWORD);
			if (!StringUtils.hasLength(password)) {
				password = generateRandomPassword();

View on GitHub (pinned to 96852e8860)

Solutions

  1. Remove either the 'properties' attribute or all <user> child elements from the <user-service> element so only one source remains
  2. If users come from an external file, move all credentials into that properties file and delete the <user> children
  3. If users are inline, delete the properties attribute and define each account with <user name=... password=... authorities=.../>
  4. Consider replacing the XML user-service entirely with a UserDetailsService @Bean for programmatic control

Example fix

// before
<security:user-service properties="classpath:users.properties">
    <security:user name="admin" password="{noop}pw" authorities="ROLE_ADMIN"/>
</security:user-service>
// after
<security:user-service properties="classpath:users.properties"/>
Defensive patterns

Strategy: validation

Validate before calling

Element elt = ...; boolean hasProps = elt.hasAttribute("properties") && !elt.getAttribute("properties").isBlank();
boolean hasUsers = ((Element) elt).getElementsByTagNameNS("http://www.springframework.org/schema/security", "user").getLength() > 0;
if (hasProps && hasUsers) throw new IllegalArgumentException("user-service: properties attribute and <user> elements are mutually exclusive");

Try / catch

// wrap context startup
try {
    new ClassPathXmlApplicationContext("security.xml");
} catch (BeanDefinitionStoreException e) {
    logger.error("Invalid <user-service> config: {}", e.getMessage());
}

Prevention

When it happens

Trigger: A <security:user-service> element declares both a non-empty 'properties' attribute and at least one <user> child element; detected in doParse when StringUtils.hasText(userProperties) is true and the <user> child list is non-empty.

Common situations: Merging XML config from two sources (e.g. one fragment adds a properties file while another appends <user> elements); converting a properties-based config to inline users without removing the attribute; copy-paste boilerplate that keeps both attributes.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/c23d9817491cd698. Report an issue: GitHub.