micro/go-micro · error
ap2: invalid signature encoding: %w
Error message
ap2: invalid signature encoding: %w
What it means
VerifyAP2Mandate decodes the mandate's Signature field using base64 RawURL encoding before performing an Ed25519 verification. This error is returned when the signature string is not valid base64url (no padding), so the signature can never be verified. It wraps the underlying base64 decode error with %w.
Source
Thrown at gateway/a2a/ap2.go:87
}
if m.Kind == "" {
return AP2SignedMandate{}, errors.New("ap2: mandate kind is required")
}
if m.IssuedAt.IsZero() {
m.IssuedAt = time.Now().UTC()
}
payload, err := ap2Payload(m)
if err != nil {
return AP2SignedMandate{}, err
}
return AP2SignedMandate{Mandate: m, KeyID: keyID, Signature: base64.RawURLEncoding.EncodeToString(ed25519.Sign(private, payload))}, nil
}
// VerifyAP2Mandate verifies a signed mandate credential.
func VerifyAP2Mandate(s AP2SignedMandate, public ed25519.PublicKey) error {
sig, err := base64.RawURLEncoding.DecodeString(s.Signature)
if err != nil {
return fmt.Errorf("ap2: invalid signature encoding: %w", err)
}
payload, err := ap2Payload(s.Mandate)
if err != nil {
return err
}
if !ed25519.Verify(public, payload, sig) {
return errors.New("ap2: mandate signature verification failed")
}
return nil
}
// AP2BindMandateToMessage returns a copy of m bound to the A2A message's task/context.
func AP2BindMandateToMessage(m AP2Mandate, msg Message) AP2Mandate {
m.TaskID = msg.TaskID
m.ContextID = msg.ContextID
return m
}
View on GitHub (pinned to 24529f1404)
Solutions
- Re-encode the signature with base64.RawURLEncoding on the signing side: base64.RawURLEncoding.EncodeToString(sig).
- If the incoming value uses padded standard base64, strip '=' and translate +/ to -_ before verification (or fix the producer).
- Log the received Signature value and confirm it is a 64-byte Ed25519 signature (86 base64url chars) and not a key or hash.
Example fix
// before (producer) sig := base64.StdEncoding.EncodeToString(signature) // after sig := base64.RawURLEncoding.EncodeToString(signature)
Defensive patterns
Strategy: validation
Validate before calling
if _, err := base64.RawURLEncoding.DecodeString(signed.Signature); err != nil {
return fmt.Errorf("signature must be base64url without padding: %w", err)
} Type guard
func validSignatureEncoding(sig string) bool {
_, err := base64.RawURLEncoding.DecodeString(sig)
return err == nil && len(sig) == 86
} Try / catch
err := a2a.VerifyAP2Mandate(signed, pub)
if err != nil && strings.Contains(err.Error(), "invalid signature encoding") {
// re-encode producer signature with base64.RawURLEncoding
} Prevention
- Always sign and encode with base64.RawURLEncoding on the producer side.
- Never pass signatures through URL query decoding; transport them in headers or JSON bodies.
- Sanity-check signature length (86 base64url chars for Ed25519) before sending.
When it happens
Trigger: Calling gateway/a2a.VerifyAP2Mandate(s, publicKey) where s.Signature contains standard base64 with padding, hex, whitespace, or any characters outside the base64url alphabet — producing 'ap2: invalid signature encoding: <decode error>'.
Common situations: A client signing with base64.StdEncoding (with '=' padding) while the gateway expects RawURLEncoding; the signature being URL-query-decoded and corrupted; a field mix-up sending a key or payload hash in the Signature field.
Related errors
- ap2: marshal mandate: %w
- ap2: mandate signature verification failed
- subscriber %v.%v has wrong number of outs: %v require signat
- subscriber %v.%v returns %v not error
- agent: StreamAsk unsupported by implementation
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/21feabffe1d74bf1.
Report an issue: GitHub.