{"record":{"id":"6174a697deb1734e","repo":"mastra-ai/mastra","slug":"failed-to-create-compact-jws-for-a2a-agent-card","errorCode":null,"errorMessage":"Failed to create compact JWS for A2A Agent Card","messagePattern":"Failed to create compact JWS for A2A Agent Card","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/server/src/server/a2a/agent-card-signing.ts","lineNumber":103,"sourceCode":"  }\n\n  const key = importSigningKey(signing);\n  const protectedHeader = getProtectedHeader(signing);\n  const encodedHeader = Buffer.from(JSON.stringify(protectedHeader), 'utf8').toString('base64url');\n  const encodedPayload = Buffer.from(canonicalPayload, 'utf8').toString('base64url');\n  const signingInput = `${encodedHeader}.${encodedPayload}`;\n  const signatureBuffer = crypto.sign(\n    getDigestAlgorithm(String(protectedHeader.alg)),\n    Buffer.from(signingInput, 'utf8'),\n    {\n      key,\n      ...getSignatureOptions(String(protectedHeader.alg)),\n    },\n  );\n  const signatureValue = signatureBuffer.toString('base64url');\n\n  if (!encodedHeader || !signatureValue) {\n    throw new Error('Failed to create compact JWS for A2A Agent Card');\n  }\n\n  const signature: AgentCardSignature = {\n    protected: encodedHeader,\n    signature: signatureValue,\n    header: signing.header,\n  };\n\n  return {\n    ...agentCard,\n    signatures: [...(agentCard.signatures ?? []), signature],\n  };\n}\n","sourceCodeStart":85,"sourceCodeEnd":117,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/a2a/agent-card-signing.ts#L85-L117","documentation":"After producing the compact JWS pieces, signAgentCard() validates that both the base64url-encoded protected header and the signature buffer are non-empty before assembling the AgentCardSignature. If either is empty — indicating the signing operation silently produced no output — it throws this error instead of attaching an invalid/empty signature to the agent card.","triggerScenarios":"The crypto sign operation returns an empty buffer or the encoded header is empty — typically a defective/zero-length signing key, an importSigningKey edge case, or a crypto backend failure that resolves without throwing.","commonSituations":"A private key imported from a malformed JWK or PEM that produces empty output; key/cert mismatched or zero-length key material in env config; unusual Node crypto backends (FIPS) altering behavior.","solutions":["Verify the private key material (PEM or JWK) is valid and non-empty; test with crypto.createPrivateKey locally.","Confirm the key type matches the alg (EC key for ES256, RSA for RS/PS).","Check that no build/bundling step stripped or zeroed the key (e.g. env var not injected at deploy time).","Log encodedHeader and the raw signature buffer before this point to isolate which piece is empty."],"exampleFix":"// before\nsigning: { privateKey: process.env.EMPTY_KEY as any, protectedHeader: { alg: 'ES256' } }\n// after\nconst pem = process.env.A2A_SIGNING_KEY; // ensure populated, valid PEM\nif (!pem) throw new Error('A2A_SIGNING_KEY not configured');\nsigning: { privateKey: pem, protectedHeader: { alg: 'ES256' } }","handlingStrategy":"validation","validationCode":"import crypto from 'node:crypto';\n// pre-flight: ensure the key imports and can sign\nconst key = typeof pem === 'string' ? crypto.createPrivateKey(pem) : crypto.createPrivateKey({ key: pem, format: 'jwk' });\ncrypto.sign('sha256', Buffer.from('test'), key); // throws early on bad key","typeGuard":"const isNonEmptyString = (s: unknown): s is string => typeof s === 'string' && s.length > 0;","tryCatchPattern":"try {\n  signedCard = await signAgentCard({ agentCard, signing });\n} catch (e) {\n  if (e.message.includes('Failed to create compact JWS')) {\n    throw new Error('Signing key produced empty output — verify A2A signing key material and alg');\n  }\n  throw e;\n}","preventionTips":["Verify key material is valid and non-empty at startup with crypto.createPrivateKey.","Ensure the key type matches the alg (EC for ES*, RSA for RS*/PS*).","Confirm the signing key env var/secret is actually injected in the deployment environment."],"tags":["a2a","jws","crypto","signing"],"backgroundTag":"empty-signature","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}