floci-io/floci · error · AwsException
TooManyTagsException
TooManyTagsException
Error message
Certificate cannot have more than " + MAX_TAGS + " tags
What it means
ACM TooManyTagsException (HTTP 400) thrown by AcmService.addTagsToCertificate when merging the new tags onto the certificate's existing tags yields more than MAX_TAGS (50) distinct keys. The limit is checked after the merge, so it is the combined total, not just the new batch, that matters.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/acm/AcmService.java:433
// Return certificate with encrypted private key
Certificate exportCert = new Certificate();
exportCert.setCertificateBody(cert.getCertificateBody());
exportCert.setCertificateChain(cert.getCertificateChain());
exportCert.setPrivateKey(encryptedKey);
return exportCert;
}
// ============ Tagging Operations ============
public void addTagsToCertificate(String certificateArn, Map<String, String> tags, String region) {
Certificate cert = getCertificateByArn(certificateArn, region);
validateTags(tags);
Map<String, String> currentTags = cert.getTags() != null ? new HashMap<>(cert.getTags()) : new HashMap<>();
currentTags.putAll(tags);
if (currentTags.size() > MAX_TAGS) {
throw new AwsException("TooManyTagsException",
"Certificate cannot have more than " + MAX_TAGS + " tags", 400);
}
cert.setTags(currentTags);
store.put(regionKey(region, cert.extractCertificateId()), cert);
}
public Map<String, String> listTagsForCertificate(String certificateArn, String region) {
Certificate cert = getCertificateByArn(certificateArn, region);
return cert.getTags() != null ? new HashMap<>(cert.getTags()) : new HashMap<>();
}
public void removeTagsFromCertificate(String certificateArn, List<Map<String, String>> tagSpecs, String region) {
Certificate cert = getCertificateByArn(certificateArn, region);
Map<String, String> currentTags = cert.getTags() != null ? new HashMap<>(cert.getTags()) : new HashMap<>();
for (Map<String, String> spec : tagSpecs) {
String key = spec.get("Key");View on GitHub (pinned to 62ff490619)
Solutions
- Reduce the request: tag fewer keys, overwrite existing keys instead of adding new ones (same key replaces, doesn't count twice), or removeTagsFromCertificate first
- Check current usage: listTagsForCertificate and compute 50 - current size before adding
- Consolidate tag keys (e.g. one 'owner' key instead of owner-team + owner-user) if a fixed large tag set is mandated
Example fix
// before
acm.addTagsToCertificate(r -> r.certificateArn(arn).tags(allSixtyTags));
// after
var current = acm.listTagsForCertificate(r -> r.certificateArn(arn)).tags();
int room = 50 - current.size();
var toAdd = newTags.entrySet().stream()
.filter(e -> !current.containsKey(e.getKey()))
.limit(Math.max(0, room))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
if (!toAdd.isEmpty()) acm.addTagsToCertificate(r -> r.certificateArn(arn).tags(toAdd)); Defensive patterns
Strategy: validation
Validate before calling
var current = acm.listTagsForCertificate(r -> r.certificateArn(arn)).tags();
int newKeys = (int) newTags.keySet().stream().filter(k -> !current.containsKey(k)).count();
if (current.size() + newKeys > 50) throw new IllegalArgumentException("tag budget exceeded"); Try / catch
try {
acm.addTagsToCertificate(r -> r.certificateArn(arn).tags(newTags));
} catch (TooManyTagsException e) {
// removeTagsFromCertificate for stale keys, then retry with a reduced set
} Prevention
- Check the 50-tag budget via listTagsForCertificate before every add
- Prefer overwriting existing keys over introducing new ones
- Remove obsolete tags when re-tagging instead of only adding
When it happens
Trigger: acm.addTagsToCertificate on a cert that already has N tags where N + (number of new distinct keys not already present) > 50. Adding a large tag map in one call, or repeated additive tagging without removal, crosses the threshold.
Common situations: Bulk-tagging scripts that append ownership metadata per team/environment until the cap is hit; copying a 60-key corporate tag policy onto ACM certs; orchestration layers ( Terraform/CFN) applying global tags on top of service-specific ones.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- InvalidNextTokenException
- ResourceInUseException
- ValidationException
- IdempotencyException
- ApiKeyLimitExceededException
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/eeb679ac18bf4bd2.
Report an issue: GitHub.