floci-io/floci · error · AwsException
InvalidArgument
InvalidArgument
Error message
Unknown tagging operation.
What it means
CloudFront exposes a single tagging endpoint (POST/GET ?Operation=...) that multiplexes TagResource and UntagResource based on the Operation query parameter. This controller only accepts Operation=Tag (with an XML Tags body) and Operation=Untag (with TagKeys); any other value — including a missing, misspelled, or wrong-case parameter — throws InvalidArgument 'Unknown tagging operation' (400).
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/cloudfront/CloudFrontController.java:974
} catch (AwsException e) {
return xmlErrorResponse(e);
}
}
@POST
@Path("/tagging")
public Response tagging(@QueryParam("Operation") String operation,
@QueryParam("Resource") String resource,
String body) {
try {
if ("Tag".equals(operation)) {
Map<String, String> tags = parseTags(body);
service.tagResource(resource, tags);
} else if ("Untag".equals(operation)) {
List<String> keys = XmlParser.extractAll(body, "Key");
service.untagResource(resource, keys);
} else {
throw new AwsException("InvalidArgument", "Unknown tagging operation.", 400);
}
return Response.noContent().build();
} catch (AwsException e) {
return xmlErrorResponse(e);
}
}
// ── Continuous Deployment Policies ───────────────────────────────────────
@POST
@Path("/continuous-deployment-policy")
public Response createContinuousDeploymentPolicy(String body) {
try {
ContinuousDeploymentPolicy policy = parseContinuousDeploymentPolicy(body);
policy = service.createContinuousDeploymentPolicy(policy);
String xml = xmlContinuousDeploymentPolicyResponse(policy);
return Response.created(URI.create("/2020-05-31/continuous-deployment-policy/" + policy.getId()))
.type(XML)View on GitHub (pinned to 62ff490619)
Solutions
- Use exactly Operation=Tag for tagging and Operation=Untag for untagging, with the Resource query parameter set to the full ARN.
- Prefer the AWS SDK's tagResource/untagResource methods, which build the correct query string.
- Check for typos and casing in the query string — matching is case-sensitive ('Tag', not 'tag').
- Verify the request goes to POST /2020-05-31/tagging with the XML body (Tags or TagKeys) matching the operation.
Example fix
# before (throws InvalidArgument: Unknown tagging operation) curl -X POST "$ENDPOINT/2020-05-31/tagging?Resource=$ARN" \ -d '<Tags><Items><Tag><Key>env</Key><Value>prod</Value></Tag></Items></Tags>' # after curl -X POST "$ENDPOINT/2020-05-31/tagging?Operation=Tag&Resource=$ARN" \ -d '<Tags><Items><Tag><Key>env</Key><Value>prod</Value></Tag></Items></Tags>'
Defensive patterns
Strategy: validation
Validate before calling
java.net.URI uri = java.net.URI.create(requestUrl);
String op = java.net.URLEncoder.encode("Tag", java.nio.charset.StandardCharsets.UTF_8);
// Assert the query string carries an accepted operation before sending
Map<String, String> q = java.net.URI.create(requestUrl).getRawQuery() == null
? Map.of() : java.util.Arrays.stream(java.net.URI.create(requestUrl).getRawQuery().split("&"))
.map(p -> p.split("=", 2)).collect(java.util.stream.Collectors.toMap(p -> p[0], p -> p[1]));
if (!("Tag".equals(q.get("Operation")) || "Untag".equals(q.get("Operation"))) || q.get("Resource") == null) {
throw new IllegalArgumentException("CloudFront tagging requires ?Operation=Tag|Untag and ?Resource=<arn>");
} Try / catch
try {
client.tagResource(r -> r.resource(arn).tags(t -> t.items(tagList)));
} catch (CloudFrontException e) {
if ("InvalidArgument".equals(e.awsErrorDetails().errorCode())
&& e.getMessage().contains("tagging")) {
// custom HTTP layer dropped/mangled the Operation query param; rebuild request
throw new IllegalStateException("Tagging request missing Operation=Tag|Untag", e);
}
throw e;
} Prevention
- Use the SDK's tagResource/untagResource rather than hand-built URLs.
- If hand-building, always include Operation=Tag or Operation=Untag (exact case) plus Resource=<arn>.
- Add a unit assertion on the outgoing query string in custom HTTP clients.
When it happens
Trigger: POST to /2020-05-31/tagging?Resource=<arn> without an Operation query parameter; Operation=tag (lowercase) or Operation=TagResource; a typo like Operation=UntagResource; calling with Operation=ListTags, which this endpoint does not support.
Common situations: SDK TagResource/UntagResource calls routed to a wrong path by a custom HTTP layer; handcrafted curl requests that forget the query param; code ported from other AWS tagging APIs that use separate endpoints per verb; case-sensitive comparisons surprising users.
Related errors
- TooManyTagsException
- InvalidArgument
- InvalidNextTokenException
- ResourceInUseException
- ValidationException
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/7df4995e21a25967.
Report an issue: GitHub.