spring-projects/spring-framework · error · BeanInitializationException

Invalid key '

Error message

Invalid key '

What it means

Thrown by PropertyOverrideConfigurer.processKey() as a BeanInitializationException when an override key does not contain the configured bean-name separator (default '.'). PropertyOverrideConfigurer requires every key to follow the 'beanName.property' shape; a key with no separator cannot be split and is therefore invalid.

Source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java:132

				if (!this.ignoreInvalidKeys) {
					throw new BeanInitializationException(msg, ex);
				}
				if (logger.isDebugEnabled()) {
					logger.debug(msg, ex);
				}
			}
		}
	}

	/**
	 * Process the given key as 'beanName.property' entry.
	 */
	protected void processKey(ConfigurableListableBeanFactory factory, String key, String value)
			throws BeansException {

		int separatorIndex = key.indexOf(this.beanNameSeparator);
		if (separatorIndex == -1) {
			throw new BeanInitializationException("Invalid key '" + key +
					"': expected 'beanName" + this.beanNameSeparator + "property'");
		}
		String beanName = key.substring(0, separatorIndex);
		String beanProperty = key.substring(separatorIndex + 1);
		this.beanNames.add(beanName);
		applyPropertyValue(factory, beanName, beanProperty, value);
		if (logger.isDebugEnabled()) {
			logger.debug("Property '" + key + "' set to value [" + value + "]");
		}
	}

	/**
	 * Apply the given property value to the corresponding bean.
	 */
	protected void applyPropertyValue(
			ConfigurableListableBeanFactory factory, String beanName, String property, String value) {

		BeanDefinition bd = factory.getBeanDefinition(beanName);

View on GitHub (pinned to 69bf83ad71)

Solutions

  1. Rewrite each key as 'beanName.property=value'.
  2. Set ignoreInvalidKeys=true so malformed or non-override keys are logged at debug instead of throwing.
  3. Move non-override keys to a different properties file consumed by a PropertyPlaceholderConfigurer instead.
  4. If you changed the separator via setBeanNameSeparator, update every key to use that separator.

Example fix

# before (broken): no separator
retryCount=5
# after
serviceClient.retryCount=5
Defensive patterns

Strategy: validation

Validate before calling

String separator = configurer.getBeanNameSeparator(); // default "."
for (String key : props.stringPropertyNames()) {
    if (key.indexOf(separator) < 0) {
        throw new IllegalStateException("Override key missing separator: " + key);
    }
}

Type guard

static boolean hasSeparator(String key, String sep) {
    return key != null && key.contains(sep);
}

Try / catch

try {
    context.refresh();
} catch (BeanInitializationException ex) {
    if (ex.getMessage().startsWith("Invalid key '")) {
        // set ignoreInvalidKeys=true or rewrite the key as beanName.property
    }
    throw ex;
}

Prevention

When it happens

Trigger: A properties line like 'timeout=30' or 'jdbc.driver' is fine, but 'myKey' with no dot at all triggers this (the first indexOf('.') returns -1). Using a non-default separator (setBeanNameSeparator) but leaving keys with dots. Accidentally including a comment-as-key or environment token without a dot.

Common situations: Leftover keys in an override file that aren't bean overrides (e.g. shared config keys, logging levels). Copying a generic properties file into the override location. Custom separator mismatch after refactoring.

Related errors


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/611258944afa82ae. Report an issue: GitHub.