Troubleshooting
This page lists the issues teams hit most often, grouped by where they occur, with the underlying cause and the fix. Most problems fall into four buckets: the embed isn’t loading, domain verification can’t see the proof, a mandate was rejected or escalated, or a third-party signature verifier is canonicalizing wrong.
Discovery: agent traffic isn’t showing up
Section titled “Discovery: agent traffic isn’t showing up”You installed the embed but the dashboard shows no agent activity.
-
The site isn’t verified yet. Discovery only records once the site is
discovery_active. Complete domain verification first. -
The script isn’t in the served HTML. View source on the live page (not the dev tools DOM) and confirm the snippet is present in the response before
</body>. The canonical install snippet is:<!-- paste before </body> --><script async src="https://cdn.sill.so/embed.js"data-site-key="sk_…"data-proof-token="pf_…"></script>A tag injected client-side by a tag manager may not run early enough — prefer a server-rendered tag.
-
A Content-Security-Policy is blocking it. If your site sends a CSP, add
https://cdn.sill.sotoscript-src(andconnect-srcfor the beacon). -
Wrong site key. The
data-site-keymust match the site in your dashboard. Re-copy it from the site’s install panel. -
The visitor wasn’t a recognized agent. Discovery matches inbound traffic against a seeded identity registry (Anthropic, OpenAI, Google, and others). Ordinary human traffic and unrecognized clients are not logged as identified agents — that is expected.
Domain verification fails
Section titled “Domain verification fails”The dashboard won’t flip the site to verified.
- The proof token isn’t reachable. Sill verifies ownership by server-fetching your domain from its origin and looking for the per-site
data-proof-tokenvalue inside the installed snippet. The proof token is opaque and per-site; the embed runtime does not read or transmit it — it exists purely so Sill can confirm the snippet is present in the merchant’s published HTML, which proves domain ownership. The token must appear in the server response, not be injected by client-side JavaScript. - The homepage didn’t return 200. A redirect chain, auth wall, geo-block, or timeout on the homepage will fail the fetch. Confirm the URL returns
200with the token to an anonymous request. - You edited the snippet. The proof token is part of the copied snippet. Paste it verbatim; don’t strip the
data-attributes.
See Domain verification for the exact record and flow.
A mandate was rejected or escalated
Section titled “A mandate was rejected or escalated”Transactional responses are discriminated by an outcome field; the HTTP status is the secondary signal. See the rejection taxonomy for the full list.
| Symptom | Likely cause | Fix |
|---|---|---|
outcome: rejected, 401 | Signature failed verification | The mandate signature didn’t verify against the agent’s key. See Signature verification fails below. |
outcome: rejected, protocol_unsupported | Protocol not in the edge allowlist | Only a2a, ap2, and mcp are admitted today. See Protocols. |
outcome: rejected, identity check | Agent not in the registry | The calling agent isn’t a recognized/registered identity. See Identifying agents. |
outcome: rejected, replay | Mandate replayed | Each mandate is single-use; reusing one is rejected. Mint a fresh, freshly-signed mandate per action. |
outcome: rejected, site mismatch | Mandate sent to the wrong site | A mandate is bound to one site; a misdirected mandate is rejected. Use the correct site_key. |
outcome: escalated, 202 | Policy escalated to review | Expected behavior — a rule’s on_fail is escalate. Resolve it in the human-in-the-loop queue; no charge occurs until resolved. |
outcome: rate_limited, 429 | Per-account or per-site limiter tripped | Honor the retry_after_seconds in the response and back off. |
Signature verification fails (your verifier)
Section titled “Signature verification fails (your verifier)”If your own code can’t verify a Sill-signed agent card or ARD catalog, the cause is almost always canonicalization:
- You used
JSON.stringifyinstead of JCS. The signing input is canonicalized with RFC 8785 (JCS). A plain serialize reorders keys and changes whitespace, so the bytes — and the signature — won’t match. Use a real JCS library. - You didn’t reconstruct the detached payload. The JWS is in detached form: the payload is omitted from the compact string and must be rebuilt from the manifest. See the verifier recipe.
- Wrong key. Match the JWS protected header
kidto the matching key in the public JWKS (kty: OKP,crv: Ed25519). - No negative control. If a tampered payload still “verifies,” your verifier isn’t actually checking the payload — add the negative-control test.
MCP requests behave unexpectedly
Section titled “MCP requests behave unexpectedly”tools/callis audited. Calls to the per-site MCP server are recorded in the audit log — that’s by design.- Session rate limit. A per-session rate limit protects the MCP endpoint; sustained bursts return
rate_limitedwith aretry_after_secondshint. Honor it and back off.
Still stuck?
Section titled “Still stuck?”Email hello@sill.so with the site_key, the approximate timestamp, and (for transactional issues) the outcome and any mandate_id from the response. Do not send signing keys or full card data.