Network#
ECA supports proxy, custom CA certificates, and mutual TLS (mTLS) for environments behind corporate firewalls or requiring client certificate authentication.
All network settings apply globally to LLM API requests and MCP HTTP transports.
Proxy#
ECA reads proxy configuration from the standard environment variables:
HTTP_PROXY="http://user:pass@host:port"
HTTPS_PROXY="http://user:pass@host:port"
http_proxy="http://user:pass@host:port"
https_proxy="http://user:pass@host:port"
Lowercase wins if both are set. Credentials (if used) must match for HTTP and HTTPS.
Bypassing the proxy#
For ECA's Hato HTTP client (including LLM API requests), set no_proxy or NO_PROXY:
export no_proxy="localhost,127.0.0.1,.internal.example"
Lowercase takes precedence even when it is empty. Entries are comma-separated; whitespace and empty entries are ignored. Matching is case-insensitive and uses the URL hostname without resolving DNS:
internal.exampleor.internal.examplematches that host and its subdomains, such asapi.internal.example, but notnotinternal.example.- IP literals match exactly; write IPv6 addresses without brackets, such as
::1. - A value of
*bypasses the configured proxy for every host. - Host entries apply to all ports and both HTTP and HTTPS. Port-qualified entries
(
internal.example:8443), CIDR ranges and partial wildcards (*.example) are not supported and do not match.
When the variable is absent or empty, or no entry matches, the configured proxy continues to be used. This bypass list applies to ECA's environment-configured Hato proxies; it does not change JVM proxy properties or other HTTP clients.
Connection and TLS errors#
A Connection closed unexpectedly message, including TLS record-layer alerts such as
bad_record_mac, indicates a failed connection but does not identify its cause. ECA
treats these failures as eligible for bounded recovery, not as a reason to disable TLS
verification.
Requests sent after tool execution have their own request-level retries on the Anthropic,
OpenAI Responses and OpenAI-compatible chat (openai-chat) APIs when no new output has
been emitted. These retries resend the same tool results without rerunning completed
tools. Once output has started, or request retries are exhausted, ECA falls back to
chat-level recovery when safe.
Chat-level recovery is limited by providers.<provider>.retry.maxAutoContinues
(default 3) per user turn, not per connection. Truncated-response continuations
share this budget. Progress shows the recovery count, and the terminal error explains
when recovery is exhausted or disabled (maxAutoContinues: 0). A new user message
starts a fresh budget. See Retry Policy and Rules.
If recovery is skipped, stderr logs Automatic recovery skipped with the reason and
count, including compaction or stopping guards. When reporting a failure, include the
surrounding [LLM-API] and [CHAT] lines for that chat ID; a TLS stack trace alone does
not explain why recovery stopped.
Other TLS failures, such as PKIX path building failed, certificate errors, or mTLS
handshake errors, can indicate a trust-store or client-certificate configuration problem.
Those failures are not automatically retried. Configure a custom CA or mTLS below when
the error points to a certificate or trust issue.
Custom CA certificates#
When behind a corporate firewall that uses its own root CA, you will see errors like PKIX path building failed. To fix this, point ECA to a PEM file containing the additional CA certificates:
{
"network": {
"caCertFile": "/etc/ssl/certs/corporate-ca.pem"
}
}
export SSL_CERT_FILE="/etc/ssl/certs/corporate-ca.pem"
NODE_EXTRA_CA_CERTS is also supported as a fallback, for compatibility with Node.js tooling.
Custom CA certificates are additive — the JVM default trust store (public CAs) remains trusted.
The config value supports dynamic string interpolation, so you can reference an env var inside the config file:
{
"network": {
"caCertFile": "${env:SSL_CERT_FILE}"
}
}
Mutual TLS (mTLS)#
For environments that require client certificate authentication, configure the client certificate and private key:
{
"network": {
"clientCert": "/etc/ssl/certs/client.pem",
"clientKey": "/etc/ssl/private/client-key.pem",
// only needed when the key is encrypted
"clientKeyPassphrase": "${env:ECA_CLIENT_KEY_PASSPHRASE}"
}
}
export ECA_CLIENT_CERT="/etc/ssl/certs/client.pem"
export ECA_CLIENT_KEY="/etc/ssl/private/client-key.pem"
export ECA_CLIENT_KEY_PASSPHRASE="optional-passphrase"
Both clientCert and clientKey must be provided together. The key must be in PKCS8 PEM format (either unencrypted or encrypted with a passphrase). RSA and EC key types are supported.
Full example#
A complete network configuration combining a custom CA with mTLS:
{
"network": {
"caCertFile": "/etc/ssl/certs/corporate-ca.pem",
"clientCert": "/etc/ssl/certs/client.pem",
"clientKey": "/etc/ssl/private/client-key.pem",
"clientKeyPassphrase": "${env:ECA_CLIENT_KEY_PASSPHRASE}"
}
}
Reference#
| Config key | Env var fallback | Description |
|---|---|---|
caCertFile |
SSL_CERT_FILE, NODE_EXTRA_CA_CERTS |
PEM file with custom CA certificates |
clientCert |
ECA_CLIENT_CERT |
PEM file with client certificate for mTLS |
clientKey |
ECA_CLIENT_KEY |
PEM file with client private key for mTLS |
clientKeyPassphrase |
ECA_CLIENT_KEY_PASSPHRASE |
Passphrase for encrypted client key |
Config values take precedence over environment variables.