windmill-labs/windmill · error · std::io::Error (AddrNotAvailable)
no pinned address to connect
Error message
no pinned address to connect
What it means
`connect_async_with_proxy` iterates over resolved candidate addresses (e.g. from DNS or a pinned proxy address) attempting a connection each time. This error is the fallback produced when the candidate list was empty or every attempt failed without recording a specific error, so there is no underlying `last_err` to surface. It wraps an `io::Error` with `ErrorKind::AddrNotAvailable` inside the crate's `WsError::Io` variant.
Source
Thrown at backend/windmill-trigger-websocket/src/proxy.rs:113
// Direct connection. Nothing to pin (IP literal or SSRF guard opted out):
// preserve the original resolve-and-connect path.
if pinned_addrs.is_empty() {
return connect_async(request).await;
}
// Pin to a validated address so this connect targets the same IP the SSRF
// guard checked. Try each in order (e.g. IPv6 then IPv4) until one connects.
let mut last_err: Option<io::Error> = None;
for addr in pinned_addrs {
match TcpStream::connect(addr).await {
Ok(socket) => {
return client_async_tls_with_config(request, socket, None, None).await;
}
Err(e) => last_err = Some(e),
}
}
Err(WsError::Io(last_err.unwrap_or_else(|| {
io::Error::new(
io::ErrorKind::AddrNotAvailable,
"no pinned address to connect",
)
})))
}
#[derive(Debug, Clone, PartialEq, Eq)]
struct ProxyTarget {
host: String,
port: u16,
/// Base64-encoded `user:pass` from URL userinfo, ready to drop into
/// the `Proxy-Authorization: Basic …` header value.
basic_auth: Option<String>,
}
/// Resolve the proxy URL string to use for outbound `(scheme, host)`.
///
/// `wss://`/`https://` reads `HTTPS_PROXY`, `ws://`/`http://` readsView on GitHub (pinned to e474e8803c)
Solutions
- Verify the proxy/WebSocket host resolves: run `getent hosts <host>` (or `nslookup`) inside the same network/container as the worker
- Check the proxy configuration (env/config file) for a typos, empty host, or wrong scheme in the proxy URL
- If behind corporate DNS, ensure the resolver is reachable from the worker container (check /etc/resolv.conf)
- Retry after fixing DNS/connectivity; the error is produced at connect time and is transient if DNS was down
Example fix
// before
let proxy = std::env::var("WS_PROXY").ok(); // may be Some("") -> no candidates
// after
let proxy = match std::env::var("WS_PROXY") {
Ok(v) if !v.trim().is_empty() => Some(v),
_ => None,
}; Defensive patterns
Strategy: retry
Validate before calling
// resolve the host before connecting
let host = proxy_host_from_config();
let resolved = tokio::net::lookup_host((host.as_str(), 443u16))
.await
.expect("proxy host must resolve");
if resolved.into_iter().next().is_none() {
return Err(anyhow!("proxy host {host} resolved to no addresses"));
} Try / catch
match connect_async_with_proxy(&url, &proxy).await {
Err(WsError::Io(e)) if e.kind() == std::io::ErrorKind::AddrNotAvailable => {
tracing::warn!("no address candidates for proxy, retrying: {e}");
// exponential backoff / fix DNS config then retry
}
Err(e) => return Err(e.into()),
Ok(_) => {}
} Prevention
- Validate proxy URLs at startup (non-empty host, correct scheme) and fail fast on bad config
- Monitor DNS health in the worker's network (alert on lookup failures)
- Use IPs or a reliable internal DNS for pinned proxy addresses
- Log every candidate address attempted so empty lists are visible in diagnostics
When it happens
Trigger: Calling `connect_async_with_proxy` (via `test_connection` or `get_consumer`) when no address candidates exist to try — e.g. the pinned proxy/socket address list is empty after DNS resolution returns nothing, or all attempts failed before setting `last_err`.
Common situations: Proxy host configured as an empty or unresolvable hostname; DNS outage in a container/K8s cluster; misconfigured `WINDMILL_TRIGGER_WS` proxy env vars; IPv6-only or IPv4-only environments where resolution yields no usable A/AAAA records.
Related errors
- Failed to fetch foundation models for AWS Bedrock
- Failed to fetch models for provider ${provider}
- Bad Gateway
- Bad Gateway
- HTTP proxy closed connection before sending CONNECT response
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/c2b15f78d3299834.
Report an issue: GitHub.