amir20/dozzle · error
failed to connect to
Error message
failed to connect to %s: %w
What it means
NewClient wraps the error from grpc.NewClient as "failed to connect to %s: %w" when the client connection cannot even be created for the endpoint. Note grpc.NewClient is lazy, so this is almost always an invalid target string (bad scheme/address) rather than the agent being down; runtime connectivity failures surface later through rpcErrToErr.
Solutions
- Fix the endpoint to host:port form (default agent port 7007), e.g. "agent-host:7007" or "host|Friendly Name"
- Drop any URL scheme (no https://) and bracket IPv6 addresses like [fd00::1]:7007
- Verify the endpoint string comes from the DOZZLE_AGENT config/labels without extra characters (spaces, quotes)
- If the agent is unreachable at runtime, check the agent container is up and port 7007 is published; the error appears on first RPC
Example fix
// before
client, _ := agent.NewClient("https://agent:7007|Agent", certs)
// after
client, err := agent.NewClient("agent:7007|Agent", certs)
if err != nil { log.Fatal().Err(err).Msg("agent endpoint invalid") } Defensive patterns
Strategy: validation
Validate before calling
if _, _, _, err := agent.ParseEndpoint(endpoint); err != nil { return err }
host, port, ok := strings.Cut(endpoint, "|")
if !strings.Contains(host, ":") { return fmt.Errorf("endpoint %q must be host:port", endpoint) } Type guard
func validEndpoint(e string) bool { addr, _, _, err := agent.ParseEndpoint(e); return err == nil && strings.Contains(addr, ":") } Try / catch
client, err := agent.NewClient(endpoint, certs)
if err != nil {
return fmt.Errorf("agent %s unreachable, check address and port 7007: %w", endpoint, err)
} Prevention
- Always configure endpoints as host:port (agent default port 7007), never URLs with schemes
- Validate endpoints with agent.ParseEndpoint at config load and fail fast
- Check agent container is running and port 7007 is published before connecting
When it happens
Trigger: agent.NewClient(endpoint, certs) where the parsed address is malformed for gRPC's resolver, e.g. missing host:port, an unsupported scheme prefix, or empty after parsing "|name|group"-style endpoints.
Common situations: Docker label/env configured endpoint like "192.168.1.5" without port instead of "192.168.1.5:7007"; DNS names with typos; IPv6 addresses not bracketed; accidentally leaving the DOZZLE_AGENT address as a URL (https://host:7007).
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- unknown code: with
- failed to parse certificate
- invalid agent endpoint
- EOF error while converting gRPC to error
- deadline exceeded: with
AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07).
Data as JSON: /api/errors/ea81b18f83cea2e0.
Report an issue: GitHub.
Appendix: source
Thrown at internal/agent/client.go:72
RootCAs: caCertPool,
InsecureSkipVerify: true, // Set to true if the server's hostname does not match the certificate
}
// Create the gRPC transport credentials
creds := credentials.NewTLS(tlsConfig)
opts = append(opts,
grpc.WithTransportCredentials(creds),
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(10*1024*1024), grpc.UseCompressor(gzip.Name)),
grpc.WithKeepaliveParams(keepalive.ClientParameters{
Time: 30 * time.Second,
Timeout: 10 * time.Second,
PermitWithoutStream: true,
}),
)
conn, err := grpc.NewClient(endpoint, opts...)
if err != nil {
return nil, fmt.Errorf("failed to connect to %s: %w", endpoint, err)
}
client := pb.NewAgentServiceClient(conn)
return &Client{
client: client,
conn: conn,
endpoint: endpoint,
nameOverride: nameOverride,
group: group,
}, nil
}
// ParseEndpoint splits an agent endpoint of the form "address|name|group" into
// its parts. Name and group are optional; address is required.
func ParseEndpoint(endpoint string) (string, string, string, error) {
parts := strings.Split(endpoint, "|")
if len(parts) > 3 || parts[0] == "" {View on GitHub (pinned to d9463cbe21)