SW-A2A-018: Agent card cannot be read
Last updated 7 November 2026
| Fact | Value |
|---|---|
| Severity | High |
| Checks | A2A agent card |
| Malicious indicator | No |
| OWASP Agentic Top 10 | ASI07 |
| OWASP MCP Top 10 | None mapped |
| NIST SP 800-53 | SI-10 (provisional mapping to SP 800-53 base controls) |
| First shipped in | Scanner 1.3.0 |
What it detects
The rule applies to a file named .well-known/agent-card.json at any depth and to each path under a2a.cards. The scanner reads such a file as strict JSON, the way A2A clients do, at most 1 MiB and 128 levels deep. It reports the file once, with one reason: too_large, bom (a byte-order mark, which A2A clients reject), not_utf8, not_json (a comment, a trailing comma, single quotes or any other syntax error), duplicate_key (a key repeated in one object, because readers disagree about which value wins), too_deep or not_an_object. A symbolic link that leaves the scan root or points at nothing, and a file the operating system refuses to read, are reported by this rule too.
No other rule runs on a card that cannot be read, so this finding stands for everything the scanner could not check. Files named agent.json under a well-known folder, and other files named agent-card.json, are cards only when they parse and have the card shape; otherwise they only get a notice.
Why it matters
A client that cannot parse the card gets nothing from it: either it refuses to talk to the agent, or a more forgiving parser reads a card that differs from the one a person reviewed. A comment or a repeated key is exactly the kind of difference that lets two readers see two cards. An unreadable card also hides the findings of every other rule. The scanner maps this rule to OWASP ASI07, Insecure Inter-Agent Communication, and to NIST SP 800-53 control SI-10, Information Input Validation.
Example
A card file whose last member ends with a comma, which strict JSON does not allow:
.well-known/agent-card.json
{
"name": "demo-agent",
"description": "Drafts release notes.",
}The finding names the file and the reason, not_json. It has no line number, and no other rule judges this card.
How to fix
Fix the syntax. Remove comments and trailing commas, save the file as UTF-8 without a byte-order mark and give each key once per object. Check the file with a strict JSON parser before you commit it. For a card that is too large, take embedded content such as images out and link to it instead.
If it is a false positive
A file at this path that is not meant as an agent card, such as a test input with deliberate errors, is still a card to the scanner. Exclude its folder in the settings, for example exclude: ["samples/**"], instead of accepting the finding, so a real card at that path is never skipped.
If the finding is not a problem in your case, accept it with a note: in the dashboard a manager or owner can accept a finding and the note is kept with it; with the scanner on its own, add it to the baseline file with a reason and an expiry date.