Existing issue check
Closest are #3861 (AdkApp↔A2aAgent comms, Gemini + Sequential agent — closed stale, not resolved) and #3020 (Vertex "model not found" — closed). Neither covers this Claude-specific A2A serving failure; searches for Anthropic/Claude + A2A return nothing.
Describe the bug
An ADK LlmAgent whose model is an Anthropic Claude model on Vertex (via google.adk.models.anthropic_llm.Claude / AnthropicLlm), deployed to Vertex AI Agent Engine as a managed A2aAgent (vertexai.preview.reasoning_engines.A2aAgent + agent_engines.create), fails to serve over A2A. On an a2a/v1/message:send call the serving instance is killed mid-request (clean SIGTERM + instance replacement) and the caller receives HTTP 400.
The same agent/topology with a Gemini model serves cleanly over the identical A2A path. The failure tracks the model, not tools/MCP.
Environment
- google-adk: 2.3.0 (2.4.0 changelog shows no related fix)
- a2a-sdk: 0.3.26 (
[http-server] extra installed)
- google-cloud-aiplatform: 1.159.x
- Runtime: Vertex AI Agent Engine (managed
A2aAgent)
- Model: Anthropic Claude on Vertex (
publishers/anthropic/models/…), region global
- Client: ADK
RemoteA2aAgent resolving the agent card (…/a2a/v1/card)
To reproduce
- Build a minimal
LlmAgent whose model is an Anthropic Claude-on-Vertex model (ADK Claude(...)), with one trivial tool or none.
- Wrap it as
A2aAgent(agent_card=…, agent_executor_builder=…) and deploy via agent_engines.create(agent_engine=A2aAgent(...), requirements=[…, "a2a-sdk[http-server]"], …).
- Wait for the engine to stabilize; confirm the card at
…/a2a/v1/card (HTTP 200).
- Send one message via
a2a/v1/message:send (e.g. through ADK RemoteA2aAgent).
Observed behavior
- The task is created, then the serving instance logs a clean
SIGTERM and a replacement container starts mid-request (~10–45s in), around/before the model turn.
- The client's
message:send returns HTTP 400; upstream this surfaces as an empty result.
- It fails even on a no-tool ping — before any tool call, no MCP involved.
- The Claude call itself works:
…:rawPredict returns 200 in the logs. So inference is fine — the break is in the native A2A serving / response-conversion path, not the model call.
Isolation
| Agent |
Model |
Tools/MCP |
A2A serve |
| control |
Gemini |
none |
PASS (clean reply, no SIGTERM) |
| minimal |
Claude (Sonnet) |
one trivial tool, no MCP |
FAIL (SIGTERM → 400) |
The only variable that tracks the failure is the model (Claude vs Gemini). A heavier Claude agent (many tools + MCP) fails the same way, and hours after deploy (ruling out a fresh-deploy confound).
Expected behavior
A Claude-on-Vertex LlmAgent served as an A2aAgent should handle message:send and return a response, as the Gemini equivalent does.
Hypothesis / notes
- Likely the Claude event/part structure (e.g. thinking blocks or streaming aggregation) differs from Gemini in a way the A2A message/event converter (
google/adk/a2a/converters/…) or the A2aAgentExecutor response path doesn't handle, taking down the serving worker.
- Untested cheap idea: disable Claude "thinking" (
thinking_budget=0) so it emits plain text/tool_use like Gemini.
- Happy to provide a fully self-contained minimal repro + engine logs on request.
Existing issue check
Closest are #3861 (AdkApp↔A2aAgent comms, Gemini + Sequential agent — closed stale, not resolved) and #3020 (Vertex "model not found" — closed). Neither covers this Claude-specific A2A serving failure; searches for Anthropic/Claude + A2A return nothing.
Describe the bug
An ADK
LlmAgentwhose model is an Anthropic Claude model on Vertex (viagoogle.adk.models.anthropic_llm.Claude/AnthropicLlm), deployed to Vertex AI Agent Engine as a managedA2aAgent(vertexai.preview.reasoning_engines.A2aAgent+agent_engines.create), fails to serve over A2A. On ana2a/v1/message:sendcall the serving instance is killed mid-request (cleanSIGTERM+ instance replacement) and the caller receives HTTP 400.The same agent/topology with a Gemini model serves cleanly over the identical A2A path. The failure tracks the model, not tools/MCP.
Environment
[http-server]extra installed)A2aAgent)publishers/anthropic/models/…), regionglobalRemoteA2aAgentresolving the agent card (…/a2a/v1/card)To reproduce
LlmAgentwhose model is an Anthropic Claude-on-Vertex model (ADKClaude(...)), with one trivial tool or none.A2aAgent(agent_card=…, agent_executor_builder=…)and deploy viaagent_engines.create(agent_engine=A2aAgent(...), requirements=[…, "a2a-sdk[http-server]"], …).…/a2a/v1/card(HTTP 200).a2a/v1/message:send(e.g. through ADKRemoteA2aAgent).Observed behavior
SIGTERMand a replacement container starts mid-request (~10–45s in), around/before the model turn.message:sendreturns HTTP 400; upstream this surfaces as an empty result.…:rawPredictreturns 200 in the logs. So inference is fine — the break is in the native A2A serving / response-conversion path, not the model call.Isolation
The only variable that tracks the failure is the model (Claude vs Gemini). A heavier Claude agent (many tools + MCP) fails the same way, and hours after deploy (ruling out a fresh-deploy confound).
Expected behavior
A Claude-on-Vertex
LlmAgentserved as anA2aAgentshould handlemessage:sendand return a response, as the Gemini equivalent does.Hypothesis / notes
google/adk/a2a/converters/…) or theA2aAgentExecutorresponse path doesn't handle, taking down the serving worker.thinking_budget=0) so it emits plain text/tool_use like Gemini.