elastic/elasticsearch · warning · IOException
repeated attribute key [{}]
Error message
repeated attribute key [{}] What it means
Thrown while reading a node's 'attributes' object: each attribute key may appear at most once. If the same key is seen twice, the parser aborts with IOException because duplicate attributes would make node role/attribute decisions ambiguous.
Source
Thrown at client/sniffer/src/main/java/org/elasticsearch/client/sniff/ElasticsearchNodesSniffer.java:197
}
publishedHost = new HttpHost(host, publishAddressAsURI.getPort(), publishAddressAsURI.getScheme());
} else if (parser.currentToken() == JsonToken.START_ARRAY && "bound_address".equals(parser.getCurrentName())) {
while (parser.nextToken() != JsonToken.END_ARRAY) {
URI boundAddressAsURI = URI.create(scheme + "://" + parser.getValueAsString());
boundHosts.add(
new HttpHost(boundAddressAsURI.getHost(), boundAddressAsURI.getPort(), boundAddressAsURI.getScheme())
);
}
} else if (parser.getCurrentToken() == JsonToken.START_OBJECT) {
parser.skipChildren();
}
}
} else if ("attributes".equals(fieldName)) {
while (parser.nextToken() != JsonToken.END_OBJECT) {
if (parser.getCurrentToken() == JsonToken.VALUE_STRING) {
String oldValue = protoAttributes.put(parser.getCurrentName(), parser.getValueAsString());
if (oldValue != null) {
throw new IOException("repeated attribute key [" + parser.getCurrentName() + "]");
}
} else {
parser.skipChildren();
}
}
} else {
parser.skipChildren();
}
} else if (parser.currentToken() == JsonToken.START_ARRAY) {
if ("roles".equals(fieldName)) {
sawRoles = true;
while (parser.nextToken() != JsonToken.END_ARRAY) {
roles.add(parser.getText());
}
} else {
parser.skipChildren();
}
} else if (parser.currentToken().isScalarValue()) {View on GitHub (pinned to db6a809a66)
Solutions
- Inspect the offending node's attributes via GET _nodes/_local/node_attrs to find the duplicate key.
- Fix the source of the duplicated attribute (elasticsearch.yml node.attr settings, or the plugin emitting it).
- If you cannot change the server, run the sniffer against a fixed node list instead of the nodes-info API.
Example fix
// before (elasticsearch.yml on node) node.attr.rack: r1 node.attr.rack: r2 // duplicate key -> sniffer fails // after node.attr.rack: r1 node.attr.zone: z2 // distinct keys
Defensive patterns
Strategy: try-catch
Try / catch
try { sniffer.sniff(); }
catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("repeated attribute key")) {
// inspect _nodes node attributes; fall back to static node list
} else throw e;
} Prevention
- Audit node.attr.* settings for accidental duplicates.
- Sniff fixed hosts if the server response is outside your control.
When it happens
Trigger: The ES nodes-info response contains a node whose attributes object lists the same key twice. Usually a sign of a malformed server response or a non-standard node-attributes source.
Common situations: Sniffing against a non-conformant or older/patched ES build that emits duplicate attribute keys; a proxy that merged attributes incorrectly; custom node attributes plugin producing duplicates.
Related errors
- expected data to start with an object
- Failed to parse content of branches.json
- Unexpected end of file
- Expected text at {} but found {}
- ordered {} are not supported
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/429501c06f8f6ec4.
Report an issue: GitHub.