spring-projects/spring-framework · error · IllegalArgumentException

'sourceMap' is required

Error message

'sourceMap' is required

What it means

Thrown by MapFactoryBean.createInstance() when sourceMap was never provided. MapFactoryBean has no sensible default content, so a missing source map is a configuration error. It is raised at bean-creation time when the Map is first requested from the factory.

Solutions

  1. Add a source map: <property name="sourceMap"><map>...</map></property> or fb.setSourceMap(Map.of(...)).
  2. For an empty map, pass an explicit empty map: fb.setSourceMap(new HashMap<>()) or <property name="sourceMap"><map/></property>.
  3. If sharing isn't needed, inject a plain Map field directly rather than using MapFactoryBean.

Example fix

// before (broken)
MapFactoryBean fb = new MapFactoryBean();
fb.getObject();
// after
MapFactoryBean fb = new MapFactoryBean();
fb.setSourceMap(Map.of("k", "v"));
Defensive patterns

Strategy: validation

Validate before calling

if (sourceMap == null) {
    sourceMap = Map.of(); // explicit empty, or fail fast
}
factoryBean.setSourceMap(sourceMap);

Type guard

static boolean hasSourceMap(MapFactoryBean fb) {
    // no public getter for sourceMap; enforce at the call site
    return true; // ensure setSourceMap was called before getObject()
}

Try / catch

try {
    return fb.getObject();
} catch (IllegalArgumentException ex) {
    if (ex.getMessage().contains("sourceMap")) {
        fb.setSourceMap(Map.of());
        return fb.getObject();
    }
    throw ex;
}

Prevention

When it happens

Trigger: A MapFactoryBean bean definition lacking <property name="sourceMap">. Programmatic use without calling setSourceMap. A <util:map> where the inner <map> element was dropped.

Common situations: Intending an empty map but omitting the property. Refactoring that removed the sourceMap element. Misunderstanding that MapFactoryBean requires a populated source even when empty.

Related errors


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

Appendix: source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/config/MapFactoryBean.java:80

		}
		if (!Map.class.isAssignableFrom(targetMapClass)) {
			throw new IllegalArgumentException("'targetMapClass' must implement [java.util.Map]");
		}
		this.targetMapClass = targetMapClass;
	}


	@Override
	@SuppressWarnings("rawtypes")
	public Class<Map> getObjectType() {
		return Map.class;
	}

	@Override
	@SuppressWarnings("unchecked")
	protected Map<Object, Object> createInstance() {
		if (this.sourceMap == null) {
			throw new IllegalArgumentException("'sourceMap' is required");
		}
		Map<Object, Object> result = null;
		if (this.targetMapClass != null) {
			result = BeanUtils.instantiateClass(this.targetMapClass);
		}
		else {
			result = CollectionUtils.newLinkedHashMap(this.sourceMap.size());
		}
		Class<?> keyType = null;
		Class<?> valueType = null;
		if (this.targetMapClass != null) {
			ResolvableType mapType = ResolvableType.forClass(this.targetMapClass).asMap();
			keyType = mapType.resolveGeneric(0);
			valueType = mapType.resolveGeneric(1);
		}
		if (keyType != null || valueType != null) {
			TypeConverter converter = getBeanTypeConverter();
			for (Map.Entry<?, ?> entry : this.sourceMap.entrySet()) {

View on GitHub (pinned to 69bf83ad71)