mastra-ai/mastra · error

Unsupported JWS algorithm for A2A Agent Card signing: ${algo

Error message

Unsupported JWS algorithm for A2A Agent Card signing: ${algorithm}

What it means

getDigestAlgorithm() maps the JWS algorithm name to a Node crypto digest by suffix: names ending in 256/384/512 map to sha256/sha384/sha512. Any algorithm not ending in one of these bit sizes (since the earlier alg whitelist passed, this is mostly a defensive check for odd names) throws this error while computing the signature buffer.

Source

Thrown at packages/server/src/server/a2a/agent-card-signing.ts:71

  if (algorithm.startsWith('ES')) {
    return { dsaEncoding: 'ieee-p1363' as const };
  }

  if (algorithm.startsWith('PS')) {
    return {
      padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
      saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST,
    };
  }

  return {};
}

function getDigestAlgorithm(algorithm: string): string {
  if (algorithm.endsWith('256')) return 'sha256';
  if (algorithm.endsWith('384')) return 'sha384';
  if (algorithm.endsWith('512')) return 'sha512';
  throw new Error(`Unsupported JWS algorithm for A2A Agent Card signing: ${algorithm}`);
}

export async function signAgentCard({
  agentCard,
  signing,
}: {
  agentCard: AgentCard;
  signing: A2AAgentCardSigningConfig;
}): Promise<AgentCard> {
  const canonicalPayload = canonicalize(stripAgentCardSignatures(agentCard));

  if (!canonicalPayload) {
    throw new Error('Failed to canonicalize A2A Agent Card for signing');
  }

  const key = importSigningKey(signing);
  const protectedHeader = getProtectedHeader(signing);
  const encodedHeader = Buffer.from(JSON.stringify(protectedHeader), 'utf8').toString('base64url');

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Use a standard alg ending in 256/384/512 (e.g. ES256, RS384, PS512).
  2. Fix truncated or misspelled alg values in the signing config.
  3. If a new algorithm is genuinely needed, extend getDigestAlgorithm to map it to a Node digest and update SUPPORTED_JWS_ALGORITHMS.

Example fix

// before
protectedHeader: { alg: 'ES256K' } // no 256/384/512 suffix mapping
// after
protectedHeader: { alg: 'ES256' }
Defensive patterns

Strategy: validation

Validate before calling

if (!/^(ES|RS|PS)(256|384|512)$/.test(alg)) {
  throw new Error(`Digest mapping requires alg ending in 256/384/512, got: ${alg}`);
}

Type guard

const hasValidDigestSuffix = (a: string): boolean =>
  a.endsWith('256') || a.endsWith('384') || a.endsWith('512');

Try / catch

try {
  return await signAgentCard({ agentCard, signing });
} catch (e) {
  if (e.message.includes('Unsupported JWS algorithm')) {
    console.error(`Signing alg '${signing.protectedHeader.alg}' has no digest mapping`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling signAgentCard where the resolved algorithm string does not end with '256', '384', or '512' — e.g. a custom/typo'd alg like 'ES256K' that slipped through, or direct calls with unusual algorithm identifiers.

Common situations: Custom algorithm aliases; misconfigured protectedHeader with truncated alg names ('ES2', 'RS'); forks/extensions adding algorithms not supported by the digest mapping.

Related errors


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