mastra-ai/mastra · error

No verification key was provided for Agent Card signature…

Error message

No verification key was provided for Agent Card signature verification

What it means

The library invokes the user-supplied options.keyProvider with the card, signature, protected header, and kid/jku/index. If it returns null or undefined, there is no key with which to verify the JWS, so it throws (per-signature) and ultimately aggregates into the verification-failed error. The keyProvider is entirely user code — this error means your key-lookup logic didn't produce a key.

Solutions

  1. Log the keyProvider input (kid/alg/jku/index) and verify your key store actually contains a key with that kid.
  2. Return a key from the keyProvider for every expected kid — export the signing public key into your JWKS/KeyVault and map kid → PEM/JWK.
  3. Fix accidental `keyProvider: async (input) => { fetchKey(input.kid) }` — missing return returns undefined; add `return`.
  4. Refresh/rotate the verifier's key cache so newly rotated server keys are visible.

Example fix

// before
keyProvider: async ({ kid }) => {
  if (kid === 'old-key') return pem;
}

// after: fall back through all known keys
keyProvider: async ({ kid }) => {
  const key = await jwks.get(kid);
  if (key) return key;
  console.warn('no key for kid', kid);
  return null;
}
Defensive patterns

Strategy: validation

Validate before calling

// ensure the keyProvider resolves for the kid the server uses, BEFORE calling the API
const header = JSON.parse(atob(card.signatures[0].protected.replace(/-/g,'+').replace(/_/g,'/')));
const key = await keyProvider({ agentCard: card, signature: card.signatures[0], protectedHeader: header, kid: header.kid, index: 0 });
if (!key) {
  throw new Error(`no verification key registered for kid=${header.kid}; publish the signing public key first`);
}

Type guard

function hasVerificationKey(k: unknown): k is NonNullable<AgentCardVerificationKey> {
  return k !== null && k !== undefined;
}

Try / catch

try {
  await client.getAgentCard();
} catch (e) {
  if (e instanceof MastraClientError && e.message.includes('No verification key was provided')) {
    await refreshKeyStore(); // reload JWKS / rotate cache, then retry
  }
}

Prevention

When it happens

Trigger: getAgentCard() with verification enabled where keyProvider returns null/undefined — e.g. the JWS header's `kid` doesn't match any key in your JWKS/key store, the keyProvider filters on alg the header doesn't match, or the provider isn't async and forgets to return the key.

Common situations: kid mismatch between server signing key and the keys published in your JWKS; keys rotated on the server but the verifier caches old keys; jku URL fetch failing silently and the provider returning null; forgetting to return the key in a synchronous keyProvider arrow function.

Related errors


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

Appendix: source

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

        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, {
        algorithms: allowedAlgorithms,
      });

      return agentCard;
    } catch (error) {
      verificationErrors.push(error instanceof Error ? error.message : 'Unknown verification failure');
    }
  }

  throw new MastraClientError(
    200,
    'OK',
    `A2A Agent Card signature verification failed: ${verificationErrors.join('; ')}`,
  );

View on GitHub (pinned to 75dd419e61)