apereo/cas · warning
Found configuration property as a Map
Error message
Found configuration property as a Map: [{}]:[{}] with values [{}] What it means
ConfigurationMetadataPropertyCreator builds Spring Boot configuration metadata from CAS @ConfigurationProperties source classes. When the default value of a property is a non-empty Map, it cannot be rendered as a simple metadata default, so this warning is emitted and the default is skipped. It signals a documentation/metadata gap, not a runtime failure of the property itself.
Solutions
- If you own the code, initialize Map-typed property fields empty (new HashMap<>() / Map.of()) and document defaults instead of embedding non-empty default maps.
- Treat the warning as informational: the property still works at runtime; only the generated metadata default is missing.
- Document the expected map keys/values in the property class javadoc or reference docs so users know the defaults.
- If defaults are needed, consider a provider/default-populator bean rather than baking them into the model field.
Example fix
// before
private final Map<String, String> actions = CollectionUtils.wrap("default", "doSomething");
// after
private final Map<String, String> actions = new HashMap<>(); Defensive patterns
Strategy: type-guard
Validate before calling
if (resultingValue instanceof Map<?, ?> mappedValue && !mappedValue.isEmpty()) {
// metadata cannot represent this default; initialize the field empty instead
} Type guard
if (!(fieldDefault instanceof Map<?, ?> m) || m.isEmpty()) {
// safe: metadata generator can process this default
} Prevention
- Initialize Map-typed configuration fields empty in CAS config model classes.
- Run metadata generation locally before committing new @ConfigurationProperties fields.
- Document map defaults in javadoc/reference docs rather than embedding them.
When it happens
Trigger: During metadata generation (build-time ConfigurationMetadataGenerator or docs generation) a config model field has a Map type whose initialized default value is non-empty, e.g. a Map field initialized with default entries in the properties class.
Common situations: CAS developers adding a new @ConfigurationProperties field typed Map<String, X> with inline default values; contributors running metadata generation and seeing warnings for recently added map-typed properties; version upgrades introducing new map defaults.
Related errors
- Unable to determine entity id to fetch metadata via MDQ for
- Failed to locate the signing key
- Skipping metadata [ ]; Either the resource cannot be…
- Skipped registration of
- No user can be accepted because none is defined
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/cc186938e478d30e.
Report an issue: GitHub.
Appendix: source
Thrown at api/cas-server-core-api-configuration-model/src/main/java/org/apereo/cas/configuration/metadata/ConfigurationMetadataPropertyCreator.java:162
}
val resultingValue = propertyField.get(classInstance);
val valueType = resultingValue.getClass();
if (valueType.isArray()) {
prop.setDefaultValue(Arrays.toString((Object[]) resultingValue));
} else if (resultingValue instanceof final Collection<?> results) {
if (!results.isEmpty()) {
val values = results.stream()
.map(Object::toString)
.collect(Collectors.joining(","));
prop.setDefaultValue(values);
}
} else if (valueType.isPrimitive() || valueType.isEnum()
|| PRIMITIVES.containsKey(valueType.getSimpleName())
|| PRIMITIVES.containsKey(elementTypeStr)) {
prop.setDefaultValue(resultingValue.toString());
} else if (resultingValue instanceof final Map<?, ?> mappedValue) {
if (!mappedValue.isEmpty()) {
LOGGER.warn("Found configuration property as a Map: [{}]:[{}] with values [{}]",
variable.getNameAsString(), valueType.getName(), mappedValue);
}
} else if (!parentClass.endsWith("Properties")) {
LOGGER.debug("Cannot determine default value; Unknown configuration property type [{}]:[{}]",
variable.getNameAsString(), valueType.getName());
}
}
} catch (final Exception e) {
LOGGER.error("Processing [{}]:[{}]. Error [{}]", parentClass, name, e);
switch (exp) {
case final LiteralStringValueExpr ex -> prop.setDefaultValue(ex.getValue());
case final BooleanLiteralExpr ex -> prop.setDefaultValue(ex.getValue());
case final FieldAccessExpr ex -> prop.setDefaultValue(ex.getNameAsString());
default -> {
}
}
}
}View on GitHub (pinned to e7288fc434)