apolloconfig/apollo · warning · BadRequestException
Config text has repeated keys: %s, please check your input.
Error message
Config text has repeated keys: %s, please check your input.
What it means
BadRequestException (HTTP 400) raised by PropertyResolver while resolving the submitted namespace config text. isHasRepeatKey lower-cases each key and tracks collisions; if any key appears more than once the offending keys are collected and reported via the %s placeholder (formatted with Guava Strings.lenientFormat, so the Set prints as [k1, k2]).
Source
Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/txtresolver/PropertyResolver.java:75
// comment items
List<ItemDTO> baseCommentItems = new LinkedList<>();
// blank items
List<ItemDTO> baseBlankItems = new LinkedList<>();
if (!CollectionUtils.isEmpty(baseItems)) {
baseCommentItems = baseItems.stream().filter(this::isCommentItem)
.sorted(Comparator.comparing(ItemDTO::getLineNum))
.collect(Collectors.toCollection(LinkedList::new));
baseBlankItems = baseItems.stream().filter(this::isBlankItem)
.sorted(Comparator.comparing(ItemDTO::getLineNum))
.collect(Collectors.toCollection(LinkedList::new));
}
String[] newItems = configText.split(ITEM_SEPARATOR);
Set<String> repeatKeys = new HashSet<>();
if (isHasRepeatKey(newItems, repeatKeys)) {
throw new BadRequestException("Config text has repeated keys: %s, please check your input.",
repeatKeys);
}
ItemChangeSets changeSets = new ItemChangeSets();
Map<Integer, String> newLineNumMapItem = new HashMap<>();// use for delete blank and comment
// item
int lineCounter = 1;
for (String newItem : newItems) {
newItem = newItem.trim();
newLineNumMapItem.put(lineCounter, newItem);
// comment item
if (isCommentItem(newItem)) {
ItemDTO oldItemDTO = null;
if (!CollectionUtils.isEmpty(baseCommentItems)) {
oldItemDTO = baseCommentItems.remove(0);
}
View on GitHub (pinned to d95fc18d11)
Solutions
- Remove or rename the duplicate key(s) listed in the error message before saving.
- Remember the comparison is case-insensitive (key and KEY collide).
- Use the repeated-keys validation client-side (see validationCode) to catch it before submit.
- Keep comment lines (starting with #) and blank lines out of the duplication check; they are ignored.
Example fix
// before timeout=10 TIMEOUT=20 // collides (case-insensitive) // after timeout=10 connect.timeout=20
Defensive patterns
Strategy: validation
Validate before calling
// Validate config text client-side exactly like PropertyResolver: case-insensitive keys,
// comment lines start with '#', blank lines ignored.
Set<String> findRepeatedKeys(String configText) {
Set<String> seen = new HashSet<>();
Set<String> dups = new HashSet<>();
for (String raw : configText.split("\\r?\\n")) {
String line = raw.trim();
if (line.isEmpty() || line.startsWith("#")) continue;
int eq = line.indexOf('=');
if (eq < 0) continue; // handled by error 143/144
String key = line.substring(0, eq).trim().toLowerCase(Locale.ROOT);
if (!seen.add(key)) dups.add(key);
}
return dups;
}
// assert findRepeatedKeys(text).isEmpty() before POST Prevention
- Run the duplicate-key check above before every save.
- Remember keys are compared case-insensitively.
- Normalize your config tooling to lowercase keys consistently.
- Exclude comment/blank lines from the check.
When it happens
Trigger: POSTing or saving namespace item text (the textarea config-text save flow) where two non-comment, non-blank lines define the same property key (case-insensitive).
Common situations: Copy-pasting a block that already contained the key; merging two property files; keys that differ only by case (Foo / foo) which the resolver folds together.
Related errors
- line:{} key value must separate by '='
- The maximum number of items (%s) for this namespace has been
- Public appNamespace not exists. NamespaceName = %s
- Params(NamespaceName) can not be empty.
- Params(NamespaceName) can not be empty.
AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14).
Data as JSON: /api/errors/c9a0783242c64b00.
Report an issue: GitHub.