mastra-ai/mastra · error
Agent Card signature is missing a protected "alg" header
Error message
Agent Card signature is missing a protected "alg" header
What it means
Each Agent Card signature is a detached JWS. The library decodes the signature's `protected` header and requires a string `alg` header parameter before verifying. This error is thrown (and collected per-signature) when the protected header either has no `alg` or the `alg` is not a string, making it impossible to select a verification algorithm.
Source
Thrown at client-sdks/client-js/src/utils/verify-agent-card-signature.ts:115
return agentCard;
}
const canonicalPayload = canonicalize(stripAgentCardSignatures(agentCard));
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');View on GitHub (pinned to 75dd419e61)
Solutions
- Fix the signer so it includes a string `alg` in the protected header (e.g. ES256 or RS256).
- Decode the `protected` segment (base64url → JSON) to confirm what header the server is actually emitting.
- Regenerate the Agent Card signature with a standard JOSE library (jose, jsonwebtoken) rather than a custom encoder.
- If the header is corrupted in transit, check for proxies/gateways rewriting the response body.
Example fix
// before: header without alg
const protectedHeader = { typ: 'JWT' };
// after
const protectedHeader = { alg: 'ES256', typ: 'JWT' }; Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: decode each signature's protected header and require a string alg
card.signatures?.forEach((sig, i) => {
const header = JSON.parse(atob(sig.protected.replace(/-/g, '+').replace(/_/g, '/')));
if (typeof header.alg !== 'string') {
throw new Error(`signature ${i} has no alg header; fix the signer before verification`);
}
}); Type guard
function hasAlgHeader(h: unknown): h is { alg: string } & Record<string, unknown> {
return typeof h === 'object' && h !== null && typeof (h as any).alg === 'string';
} Try / catch
try {
await client.getAgentCard();
} catch (e) {
if (e instanceof MastraClientError && e.message.includes('missing a protected "alg" header')) {
// fall back to unverified card or surface a clear config error
}
} Prevention
- Sign Agent Cards with a standard JOSE library so the protected header always includes alg.
- Decode and inspect the protected header of served signatures during server-side integration tests.
- Reject placeholder/mock signatures in development fixtures.
When it happens
Trigger: getAgentCard() with verification enabled where the card's signatures[i].protected base64url-decodes to a JOSE header lacking a string `alg` (e.g. header is {"typ":"JWT"} or alg: null).
Common situations: Signer produced the JWS without an alg (rare, but possible with hand-rolled signers); a corrupted or truncated `protected` segment; a mock fixture with an empty/placeholder protected header; server library version producing headers this verifier rejects.
Related errors
- Agent Card signature algorithm "${protectedHeader.alg}" is n
- A2A Agent Card signature verification failed: ${verification
- Expected a PEM-encoded public key or certificate string for
- Failed to canonicalize A2A Agent Card for signature verifica
- No verification key was provided for Agent Card signature ve
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/979a41f2c9c5e078.
Report an issue: GitHub.