mastra-ai/mastra · error

Agent Card signature algorithm "${protectedHeader.alg}" is n

Error message

Agent Card signature algorithm "${protectedHeader.alg}" is not allowed

What it means

After confirming a string `alg` exists, the library checks it against the allowed algorithm list — either options.algorithms or the defaults (ES256/384/512, RS256/384/512, PS256/384/512). If the signature's alg is outside this list (e.g. HS256, EdDSA, none), it throws and records the error per signature; if all signatures fail, the aggregate error is raised.

Source

Thrown at client-sdks/client-js/src/utils/verify-agent-card-signature.ts:119

  if (!canonicalPayload) {
    throw new MastraClientError(200, 'OK', 'Failed to canonicalize A2A Agent Card for signature verification');
  }

  const allowedAlgorithms = options.algorithms ?? [...DEFAULT_AGENT_CARD_SIGNATURE_ALGORITHMS];
  const encodedPayload = base64url.encode(canonicalPayload);
  const verificationErrors: string[] = [];

  for (const [index, signature] of signatures.entries()) {
    try {
      const compactJws = `${signature.protected}.${encodedPayload}.${signature.signature}`;
      const protectedHeader = decodeProtectedHeader(compactJws);

      if (typeof protectedHeader.alg !== 'string') {
        throw new Error('Agent Card signature is missing a protected "alg" header');
      }

      if (!allowedAlgorithms.includes(protectedHeader.alg)) {
        throw new Error(`Agent Card signature algorithm "${protectedHeader.alg}" is not allowed`);
      }

      const verificationKey = await options.keyProvider({
        agentCard,
        signature,
        protectedHeader,
        alg: protectedHeader.alg,
        kid: typeof protectedHeader.kid === 'string' ? protectedHeader.kid : undefined,
        jku: typeof protectedHeader.jku === 'string' ? protectedHeader.jku : undefined,
        index,
      });

      if (!verificationKey) {
        throw new Error('No verification key was provided for Agent Card signature verification');
      }

      const importedKey = await importVerificationKey(verificationKey, protectedHeader.alg);
      await compactVerify(compactJws, importedKey, {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Make the server sign the Agent Card with an allowlisted asymmetric algorithm (ES256 or RS256 recommended).
  2. If the server's algorithm is acceptable, extend options.algorithms — e.g. algorithms: ['ES256','EdDSA'] — and ensure importVerificationKey supports it.
  3. If you intentionally narrowed algorithms, align your keyProvider to return keys matching the algorithms the server actually uses.
  4. Check the signature's protected header (decode base64url) to see the exact alg being rejected.

Example fix

// before
await getAgentCard(); // client default algorithms only

// after: allow the server's EdDSA keys
const client = new MastraClient({ baseUrl, verifyAgentCardSignature: { keyProvider, algorithms: ['ES256', 'EdDSA'] } });
Defensive patterns

Strategy: validation

Validate before calling

// before enabling verification, check the server's alg against your allowlist
const DEFAULTS = ['ES256','ES384','ES512','RS256','RS384','RS512','PS256','PS384','PS512'];
const header = JSON.parse(atob(card.signatures[0].protected.replace(/-/g,'+').replace(/_/g,'/')));
if (!(options.algorithms ?? DEFAULTS).includes(header.alg)) {
  console.warn(`server signs with ${header.alg}; add it to options.algorithms or change the signer`);
}

Type guard

function isAllowedAlg(alg: string, allowed: readonly string[]): alg is typeof allowed[number] {
  return (allowed as readonly string[]).includes(alg);
}

Try / catch

try {
  await client.getAgentCard();
} catch (e) {
  if (e instanceof MastraClientError && /algorithm .* is not allowed/.test(e.message)) {
    // adjust options.algorithms or re-sign server-side, then retry once
  }
}

Prevention

When it happens

Trigger: getAgentCard() with verification enabled where a signature's protected header declares an algorithm not in options.algorithms ?? DEFAULT_AGENT_CARD_SIGNATURE_ALGORITHMS — commonly 'HS256' (symmetric signer), 'EdDSA', or '"alg":"none"'.

Common situations: Server signs with EdDSA (Ed25519) which is not in the default allowlist; developer restricts options.algorithms to RS256 but server uses ES256; symmetric HS signing misused for public card verification.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/e9bafd1731e938a9. Report an issue: GitHub.