Agent Card validation errors explained, one by one

12 min read
1name · description · versionerror2supportedInterfaces[] · url · protocolBinding · protocolVersionerror3capabilities · defaultInputModes · defaultOutputModeserror4skills[] · id · name · description · tagserror5securitySchemes · securitywarning6provider · signatures[]warning
Checks run top to bottom. Layers 1–4 can produce errors that block interoperability; 5 and 6 only ever advise.

Validator output is only useful if you know which findings block interoperability and which are advice. This walks all six layers of checks in the order they run, with the trigger and the fix for every message — including the ones whose severity changes depending on what else is in your card.

How to read the output

Every check below comes from the A2A specification. Findings come in three severities, and the distinction is not cosmetic:

  • Error — the card cannot do its job. A client either cannot parse it, cannot find your endpoint, or cannot tell what you do. Fix all of these before publishing.
  • Warning — the card works but under-delivers, or it contains something that will bite you. Some warnings are trivial; one of them (an embedded credential) is the most serious thing the validator can find.
  • Pass — a check that had something to confirm. An empty pass list on a card with no errors usually means the document is far thinner than you think.

Checks run in layers, and later layers assume earlier ones held. That is why fixing the first error often removes several others at once — and why working bottom-up wastes time.

Layer 0 — JSON that will not parse

Message
Invalid JSON: Unexpected token } in JSON at position 412

Nothing else runs until this passes. In hand-written cards the cause is almost always one of three things: a trailing comma after the last item in an array or object, a smart quote pasted in from a document, or a raw newline inside a string literal. JSON allows none of them.

Multi-line descriptions are the usual culprit. If you want a long description, keep it on one logical line and let your editor soft-wrap it, or build the card from code rather than editing JSON by hand.

Layer 1 — pre-1.0 fields

Message (one per field found)
Top-level "url" is a pre-1.0 field.
A2A v1.0 moved it to supportedInterfaces[0].url.

Five top-level fields were relocated or renamed in v1.0. Finding any of them tells the validator this is a migration in progress, which changes how it reports everything downstream.

Pre-1.0 fieldWhere it went
urlsupportedInterfaces[0].url
preferredTransportordering of supportedInterfaces[] — first entry is preferred
additionalInterfacesfurther entries in supportedInterfaces[]
protocolVersionsupportedInterfaces[].protocolVersion
supportsAuthenticatedExtendedCardcapabilities.extendedAgentCard

Layer 2 — identity

MessageSeverityFix
Missing required identity field: name.errorAdd a name. Use the agent's product name, not a service id
Missing required identity field: description.errorSay what the agent does and when to route work to it
Description is present but short…warningUnder 20 characters. Expand to include the boundary of what it will not do
Missing required field: version.error*The version of your agent ("1.2.0"), not the protocol

* downgraded to a warning on cards that still carry pre-1.0 fields, per the previous section.

The short-description warning is worth more than its severity suggests. This field is read by another agent's model to make a routing decision. "Invoice agent" is syntactically fine and practically useless; a description that names the inputs it expects and the cases it declines is what gets you correctly invoked — and, just as valuably, correctly skipped.

Layer 3 — interfaces and endpoints

This layer produces more errors than any other, because one array carries four separate requirements.

Message
Missing service endpoint. A2A v1.0 requires supportedInterfaces[]
with at least one { url, protocolBinding, protocolVersion } entry.

Raised when there is no supportedInterfaces array and no legacy top-level url to fall back on. This is the finding to fix first: without it, nothing can address your agent at all.

MessageSeverityTrigger and fix
supportedInterfaces[0] must be an object.errorA bare string in the array. Each entry is an object with three keys
supportedInterfaces[0] is missing url.errorAbsolute URL of the endpoint, including scheme and path
supportedInterfaces[0] is missing protocolBinding.errorOne of JSONRPC, GRPC, HTTP+JSON, or a custom binding URI
protocolBinding "REST" is not a core binding…warningNot a recognised value. Use HTTP+JSON, or identify a genuinely custom binding by URI
supportedInterfaces[0] is missing protocolVersion.errorThe A2A version this endpoint speaks — "1.0", not your agent's version
Endpoint … is not a valid URL.errorUsually a missing scheme (agents.example.com/a2a rather than https://agents.example.com/a2a)
Endpoint … is not HTTPS.warningFine for localhost during development; the spec requires encrypted transport in production

Layer 4 — capabilities and content modes

MessageSeverityFix
Missing required field: capabilities.error*Add the object even if everything in it is false — its absence is ambiguous, its contents are not
capabilities.stateTransitionHistory is not part of A2A v1.0.warningRemoved in v1.0. Delete it, or model the behaviour as an extension
defaultInputModes should list supported input media types…warningIANA media types, e.g. ["text/plain", "application/json"]
defaultOutputModes should list supported output media types…warninge.g. ["application/json"]

The two mode fields are required by the specification but reported as warnings, and that gap is deliberate: a caller missing your mode list can still attempt a request and negotiate, whereas a caller missing your endpoint cannot do anything at all. Severity here tracks what breaks, not what the spec text says. Fix them anyway — guessing what to send is not a good first experience.

Layer 4b — skills

Message
skills must include at least one skill describing what the agent can do.

A card with no skills describes an agent that accepts nothing. Then each skill is checked on four fields:

MessageSeverityFix
skills[0] must be an object.errorA bare string in the array
skills[0] is missing id.errorStable machine identifier, kebab-case: order-investigation
skills[0] is missing name.errorShort human-readable label
skills[0] is missing description.errorWhat the skill takes and what it returns
skills[0] description is short…warningUnder 20 characters. Add task boundaries and expected inputs
skills[0] is missing tags.errorA non-empty array. Required in v1.0 — tags drive skill discovery

Missing tags is the most common error on real cards, because they were optional in pre-1.0 drafts. Tag with the words someone searching for the capability would use rather than your internal vocabulary: ["invoices", "reconciliation", "finance"], not ["fin-svc-v2"].

A skill that passes every check
{
  "id": "reconcile-payment-batch",
  "name": "Reconcile a payment batch",
  "description": "Given a bank statement export, match each line to an open
                  invoice and report exceptions with reasons.",
  "tags": ["finance", "invoices", "reconciliation"],
  "examples": ["Reconcile yesterday's ACH batch against open invoices."]
}

Layer 5 — security metadata

Message
Authentication is not declared. Add securitySchemes and security
requirements when the endpoint is not fully public.

Raised when the card declares neither securitySchemes nor security. That is correct for a genuinely open agent and a serious omission for anything else — a caller reading your card has no way to know a credential is needed until it gets a 401 it did not plan for.

Message
The card appears to contain an API key (sk-...). Agent Cards are public
discovery documents; declare securitySchemes instead of embedding credentials.

This one is a warning by severity and an incident by consequence. The scan looks for the recognisable shapes — sk-… keys, JWTs, AWS access key ids, GitHub tokens, bearer headers — anywhere in the serialised document, including inside descriptions and examples where they usually arrive by copy-paste.

Layer 6 — provider and signatures

MessageSeverityFix
provider metadata is missing.warningAdd provider.organization and provider.url — directories and marketplaces use them to attribute your agent
provider.name is a pre-1.0 field.warningRenamed to provider.organization in v1.0

Nothing in this layer blocks a request, which is exactly why it gets skipped. It is also what a human decides with: an unsigned card from an unnamed provider is hard to justify approving in a partner review, however valid the JSON is.

If your card carries signatures, the validator confirms their presence as a pass. Verifying them is a separate operation — a JWS over the card canonicalised per RFC 8785 — but publishing them at all signals that the document is meant to be checked.

Triage order

Work top-down. Each step assumes the previous one holds, so this order minimises re-runs:

  1. Make it parse. Nothing else runs until it does.
  2. Restructure the transport section. If pre-1.0 field warnings appear, fix supportedInterfaces before anything else — it silently changes the severity of later findings.
  3. Clear every error. Identity, interfaces, capabilities, skills. These are the interoperability blockers.
  4. Deal with any credential warning immediately, regardless of where it sits in the list.
  5. Close the remaining warnings. Modes, security declarations, provider metadata — each one is a question a caller would otherwise have to ask you.
  6. Check the live URL. Validation covers the document — including that it sits at the RFC 8615 well-known path; the well-known URL checker covers the delivery — path, status code and content type on your real domain.

Paste your card into the Agent Card validator to run all of these at once, or read the schema reference for the field-level detail behind any single message.

Frequently asked questions

My card passes validation but nothing discovers it. Why?

Validation checks the document, not the delivery. A perfectly valid card served at the wrong path, without HTTPS, with the wrong content type, or without a CORS header is still undiscoverable. Check the live URL separately with a well-known URL checker after every deploy.

Are warnings safe to ignore?

Some are, and some are the most consequential findings in the report. Missing defaultInputModes is a warning but leaves callers guessing what to send; an embedded credential is a warning but is a security incident. Treat warnings as a reading list, not a backlog you can defer wholesale.

Why is a missing version sometimes an error and sometimes a warning?

Because the validator detects pre-1.0 cards. If the document still carries top-level url or preferredTransport, it is mid-migration, and reporting every v1.0 requirement as a hard error buries the one finding that matters — that the transport section needs restructuring. Once supportedInterfaces exists, the same omissions become errors.

Does the validator check that my endpoint is reachable?

No. It checks that the URLs in the card are syntactically valid and use HTTPS. Whether anything answers at those addresses is a different question, and an important one: an interface listed in the card is a promise a caller will act on.

What is the single most common error?

Missing skill tags. They were optional in pre-1.0 drafts and are required in v1.0, so almost every card written before the change fails on it — and because tags drive skill-level discovery, a card missing them is findable but not matchable.

References

  1. A2A protocol specification (a2aproject/A2A)github.com/a2aproject/A2A
  2. RFC 8615 — Well-Known Uniform Resource Identifierswww.rfc-editor.org/rfc/rfc8615
  3. RFC 8785 — JSON Canonicalization Scheme (JCS)www.rfc-editor.org/rfc/rfc8785
  4. IANA media types registrywww.iana.org/assignments/media-types/media-types.xhtml

Related tool: Agent Card Validator

Next step

Paste your card. Get the list.

The validator runs every check on this page against your JSON — required fields, interface shape, skill tags, pre-1.0 leftovers and embedded credentials — and tells you which ones block interoperability.