Configuration Reference

Complete reference of all configuration options across a2a-rust crates.

Server Configuration

RequestHandlerBuilder

OptionTypeDefaultDescription
with_agent_cardAgentCardNoneDiscovery card for /.well-known/agent-card.json
with_task_storeimpl TaskStoreInMemoryTaskStoreCustom task storage backend
with_task_store_configTaskStoreConfig1hr TTL, 10k capacityTTL and capacity for default store
with_push_config_storeimpl PushConfigStoreInMemoryPushConfigStoreCustom push config storage
with_push_senderimpl PushSenderNoneWebhook delivery implementation
with_interceptorimpl ServerInterceptorEmpty chainServer middleware
with_executor_timeoutDuration1 hourMax time for executor completion (DEFAULT_EXECUTOR_TIMEOUT); without_executor_timeout() removes the bound
with_event_queue_capacityusize256Bounded channel size per stream. Increased from 64 to push the per-event cost inflection from ~52 to ~252 events. Increase further for tasks producing >250 events.
with_max_event_sizeusize16 MiBMax serialized SSE event size
with_max_concurrent_streamsusize1,024Limit concurrent SSE connections (pass usize::MAX to disable)
with_metricsimpl MetricsNoopMetricsMetrics observer for handler activity
with_handler_limitsHandlerLimitsSee belowConfigurable validation limits
allow_undeclared_input_modes()—OffAccept message parts whose mediaType the card's input modes do not declare; by default, when the card declares any, such a part is refused with ContentTypeNotSupportedError

HandlerLimits

FieldTypeDefaultDescription
max_id_lengthusize1,024Maximum task/context ID length
max_metadata_sizeusize1 MiBMaximum serialized metadata size
max_cancellation_tokensusize10,000Cleanup sweep threshold
max_token_ageDuration1 hourStale token eviction age
push_delivery_timeoutDuration5sPer-webhook delivery timeout
push_delivery_budgetDuration30sTotal push-delivery time per event, across all configs
executor_drain_timeoutDuration5sBound on the blocking path's wait for the queue to close after the executor finished; also how long a continuation waits for a parked (input-required/auth-required) turn's executor to return
max_artifacts_per_taskusize1,000Maximum artifacts per task (prevents O(n²) serialization)
max_context_locksusize10,000Max per-context locks before cleanup
max_push_configs_per_taskusize100Maximum push configs per task (uniform across store backends)
max_parts_per_artifactusize10,000Maximum parts a single artifact may accumulate
max_total_push_configsusize100,000Global push-config ceiling across all tasks
subscribe_reattach_intervalDuration250msHow often an idle SubscribeToTask stream re-checks whether its task finished, once the turn's queue closed
subscribe_max_idleDuration5 minHow long a SubscribeToTask stream waits on a parked task before ending; the client resubscribes
subscribe_replay_limitusize1,000Maximum logged events a Last-Event-ID resumption replays. The offset is client-supplied, so the cap bounds the read; every replayed frame carries its own id:, so a truncated replay is resumable
subscribe_replay_catchupDuration2sHow long a resuming stream waits for the event log to catch up with what was already broadcast. Zero disables the wait; on expiry the shortfall is logged and counted under event_log_catchup

Build-time validation: max_id_length, max_metadata_size, and push_delivery_timeout must be non-zero. Zero values are rejected by RequestHandlerBuilder::build().

TaskStoreConfig

FieldTypeDefaultDescription
max_capacityOption<usize>10,000Maximum stored tasks; oldest terminal tasks evicted on overflow
task_ttlOption<Duration>1 hourTTL for completed/failed tasks
eviction_intervalu6464Writes between automatic eviction sweeps
max_page_sizeu321,000Maximum tasks per page in list queries
max_events_per_taskOption<usize>512Events one task's log keeps for Last-Event-ID resumption; None removes the bound
idempotency_key_ttlOption<Duration>24 hoursHow long an idempotency key is honoured, matching the SQL stores' one day; None keeps keys forever

InMemoryPushConfigStore

ConstructorDefaultDescription
::new()100Default max push configs per task
::with_max_configs_per_task(N)—Custom per-task push config limit

DispatchConfig

Shared configuration for JSON-RPC, REST, and Axum dispatchers. Pass to JsonRpcDispatcher::with_config(), RestDispatcher::with_config(), or A2aRouter::with_config().

FieldTypeDefaultDescription
max_request_body_sizeusize4 MiBLarger bodies return 413
body_read_timeoutDuration30sSlow loris protection
max_query_string_lengthusize4,096REST only; longer queries return 414
sse_keep_alive_intervalDuration30sPeriodic keep-alive comment interval for SSE streams
sse_channel_capacityusize64SSE response body channel buffer size
max_batch_sizeusize100Maximum requests in a JSON-RPC batch
require_version_headerbooltrueReject a data-plane request with no A2A-Version header as VersionNotSupported (spec §3.6.2: absent means 0.3)

GrpcConfig

Configuration for the gRPC dispatcher (requires grpc feature).

FieldTypeDefaultDescription
max_message_sizeusize4 MiBMaximum inbound/outbound message size
concurrency_limitusize256Max concurrent gRPC requests per connection
stream_channel_capacityusize64Bounded channel for streaming responses
require_version_headerbooltrueReject a call with no a2a-version metadata as VersionNotSupported

PushRetryPolicy

Configurable retry policy for HttpPushSender. Pass via HttpPushSender::with_retry_policy().

FieldTypeDefaultDescription
max_attemptsusize3Maximum delivery attempts
backoffVec<Duration>[1s, 2s]Backoff durations between retries

RateLimitConfig

FieldTypeDefaultDescription
requests_per_windowu64100Max requests per caller per window
window_secsu6460Window duration in seconds
trusted_proxy_hopsusize0How many X-Forwarded-For hops to trust (0 = ignore XFF entirely)
max_bucketsusize10,000Hard bound on tracked caller buckets (fail-closed when full)

ServeConfig

Limits for a Server (Server::bind(addr).await?.with_config(config)). The three shutdown phases run in order — completion_grace, then task_grace, then drain_timeout — and the gRPC and WebSocket dispatchers' serve_with_shutdown take the same three through their own with_completion_grace, with_task_grace and with_drain_timeout.

FieldTypeDefaultDescription
max_connectionsOption<usize>NoneCeiling on connections served at once; None is unbounded
completion_graceDuration5sOn shutdown, how long in-flight tasks get to finish on their own before they are cancelled (DEFAULT_COMPLETION_GRACE)
task_graceDuration10sHow long cancelled tasks get to cancel what they delegated and write a terminal event (DEFAULT_TASK_GRACE)
drain_timeoutDuration15sHow long connections get to finish before they are reported abandoned (DEFAULT_DRAIN_TIMEOUT)
header_read_timeoutOption<Duration>30sHow long a peer may take to send complete request headers; None disables
idle_timeoutOption<Duration>75sHow long a connection may carry no traffic before it is closed; None disables

Internal Limits

LimitValueDescription
Event queue typebroadcastFan-out to multiple subscribers; a reader that falls behind the ring receives a streamLagged error and its stream ends (no silent gap)
Rate limiter cleanup interval256 checksStale buckets (from departed callers) evicted every 256 check() calls
Rate limiter window CASLock-freeWindow transitions use compare_exchange to avoid TOCTOU races
Credential store poisoningFail-fastInMemoryCredentialsStore panics on poisoned locks rather than returning None

Client Configuration

ClientBuilder

OptionTypeDefaultDescription
with_protocol_bindingimpl Into<String>"JSONRPC" (new); the card's interface chosen by preferred_bindings (from_card)Transport: "JSONRPC", "HTTP+JSON" (alias "REST"), or "GRPC" — the last needs build_grpc(); build() refuses it
with_timeoutDuration30sPer-request timeout
with_connection_timeoutDuration10sTCP connection timeout
with_stream_connect_timeoutDuration30sEstablishing a stream: until the response headers (gRPC: until the call is accepted)
with_stream_first_event_timeoutDuration5 minWait for a stream's first data (an event or a keep-alive) once established
with_max_event_sizeusize16 MiBLargest single stream event accepted; larger ones are refused and skipped
with_stream_idle_timeoutOption<Duration>5 minLongest an established stream may receive nothing — keep-alive comments count — after its first data; None disables
with_retry_policyRetryPolicyNoneRetry on transient errors with jittered backoff
with_accepted_output_modesVec<String>["text/plain", "application/json"]MIME types accepted
with_history_lengthu32NoneMessages in responses
with_return_immediatelyboolfalseDon't wait for completion
with_tenantimpl Into<String>None (auto from AgentCard)Tenant sent on every request (spec §8.3.2 rule 4); a per-request tenant overrides it
with_grpc_bare_address_schemeGrpcBareAddressSchemeHttpsExceptLoopbackHow build_grpc dials a card's bare host:port gRPC target: TLS except for loopback (default), always TLS, or always plaintext
with_grpc_tls_configClientTlsConfigNone (bundled Mozilla roots)grpc-tls feature: the TLS settings build_grpc uses for an https:// endpoint, explicit or policy-chosen — a private CA, a client certificate, or a server name that differs from the host
with_interceptorimpl CallInterceptorEmpty chainClient middleware

GrpcTransportConfig

Configuration for the gRPC client transport (requires grpc feature). The struct is #[non_exhaustive]: build it with GrpcTransportConfig::default() and the with_* setters.

FieldTypeDefaultDescription
timeoutDuration30sPer-request timeout
connect_timeoutDuration10sConnection timeout
max_message_sizeusize4 MiBMaximum message size
stream_channel_capacityusize64Streaming response buffer
bare_address_schemeGrpcBareAddressSchemeHttpsExceptLoopbackScheme used for a bare host:port target (an http:///https:// URL is used as-is)
tls_configOption<ClientTlsConfig>None (bundled Mozilla roots)grpc-tls feature: pin a private CA or present a client certificate for https:// endpoints

RetryPolicy

FieldTypeDefaultDescription
max_retriesu323Maximum retry attempts
initial_backoffDuration500msBackoff before first retry
max_backoffDuration30sCaps exponential growth
backoff_multiplierf642.0Multiplier per retry

SSE Parser Limits

LimitValueDescription
Event size16 MiB (ClientBuilder::with_max_event_size)Largest single stream event; larger ones are refused with an error and skipped, and a line that outgrows it is refused as soon as it does (aligned with server)
Stream connect timeout30s (with_stream_connect_timeout)Until the response headers; the first event then has its own 5-minute bound

HTTP Caching (Agent Card)

HeaderDefaultDescription
Cache-Controlpublic, max-age=3600Configurable max-age (default 1 hour)
ETagAuto-computedContent hash
Last-ModifiedAuto-setTimestamp of last change

Feature Flags

a2a-protocol-server

FeatureDefaultDescription
signingOffForwards a2a-protocol-types/signing; the server itself neither signs nor verifies the card it serves
tracingOnStructured logging via tracing crate; default-features = false compiles it out
tls-rustlsOffHTTPS delivery for the bundled push-notification sender
sqliteOffSQLite-backed task and push config stores via sqlx
postgresOffPostgreSQL-backed task and push config stores via sqlx
websocketOffWebSocket transport via tokio-tungstenite
grpcOffgRPC transport via tonic (plaintext listener)
grpc-tlsOffTLS on the gRPC listener itself: GrpcDispatcher::with_tls(ServerTlsConfig) with a server identity and, optionally, a client CA for mutual TLS; implies grpc; the TLS types are re-exported from dispatch::grpc
otelOffOpenTelemetry metrics and spans via opentelemetry-otlp / tracing-opentelemetry (implies tracing)
conformanceOffA harness that grades an AgentExecutor against the protocol's invariants
axumOffAxum framework integration (A2aRouter)
auth-jwtOffJWT bearer-token authentication (JwtAuthInterceptor)

a2a-protocol-client

FeatureDefaultDescription
signingOffForwards a2a-protocol-types/signing; the client itself neither signs nor verifies anything
tracingOnStructured logging via tracing crate; default-features = false compiles it out
tls-rustlsOnHTTPS via rustls (no OpenSSL dependency); default-features = false for a plaintext-only build
websocketOffWebSocket transport via tokio-tungstenite
grpcOffgRPC transport via tonic (plaintext; https:// is refused with a message naming grpc-tls)
grpc-tlsOffgRPC over TLS: implies grpc (not tls-rustls), verifies against the bundled Mozilla roots or a supplied ClientTlsConfig (re-exported from transport::grpc)
testingOffA scripted hostile peer (testing::ScriptedPeer) that stalls, cuts off, mis-frames or refuses on each binding, for testing code that calls agents

a2a-protocol-types

FeatureDefaultDescription
signingOffJWS/ES256 agent card signing (RFC 8785 canonicalization)
protoOffCanonical protobuf message types and the JSON⇄proto conversions (turned on by grpc)

a2a-protocol-sdk (umbrella)

FeatureDefaultDescription
signingOffEnables signing in all sub-crates
tracingOnEnables tracing in client and server
tls-rustlsOnEnables tls-rustls in client and server
grpcOffEnables grpc in client and server
grpc-tlsOffEnables grpc-tls in the client and the server: https:// dialling on one side, GrpcDispatcher::with_tls on the other
websocketOffEnables websocket in client and server
sqliteOffEnables sqlite in the server
postgresOffEnables postgres in the server
otelOffEnables otel in the server
axumOffEnables axum in the server
auth-jwtOffEnables auth-jwt in the server

Environment Variables

VariableDescription
RUST_LOGLog level filter (when the tracing feature is enabled — every crate's default — and a subscriber reads it)

Examples:

RUST_LOG=info              # Info and above
RUST_LOG=debug             # Debug and above
RUST_LOG=a2a_protocol_server=debug  # Debug for server crate only
RUST_LOG=a2a_protocol_server=trace,a2a_protocol_client=debug  # Per-crate levels

Next Steps