t8y2/dbx · critical

No etcd endpoint configured

Error message

No etcd endpoint configured

What it means

probeClient returns this error when it exhausted all configured endpoints without recording a failure — which only happens when the endpoint list was empty to begin with. The library refuses to dial etcd with zero endpoints, so an empty or unparsable endpoint configuration surfaces here from connect or validateConnection.

Source

Thrown at agents/drivers/etcd-go/client.go:333

	var lastFailure error
	for _, endpoint := range endpoints {
		ctx, cancel := context.WithTimeout(context.Background(), rpcTimeoutSeconds*time.Second)
		_, err := client.Maintenance.Status(ctx, endpoint)
		cancel()
		if err == nil {
			return map[string]any{"ok": true, "endpoint": endpoint}, nil
		}
		// A restricted etcd user may not be allowed to call Maintenance.Status.
		// PERMISSION_DENIED still proves that the channel reached an etcd server.
		if status.Code(err) == codes.PermissionDenied {
			return map[string]any{"ok": true, "endpoint": endpoint, "limited": true}, nil
		}
		lastFailure = err
	}
	if lastFailure != nil {
		return nil, lastFailure
	}
	return nil, errors.New("No etcd endpoint configured")
}

func connectionEndpoints(connection connectionParams) []string {
	configured := firstNonBlank(connection.EtcdEndpoints, connection.Endpoints, connection.ConnectionString)
	var result []string
	if configured != "" {
		for _, endpoint := range strings.FieldsFunc(configured, func(r rune) bool { return r == ',' || r == '\n' }) {
			normalized := normalizeEndpoint(strings.TrimSpace(endpoint), connection.SSL)
			if normalized != "" {
				result = append(result, normalized)
			}
		}
	}
	if len(result) == 0 {
		host := connection.Host
		if host == "" {
			host = "127.0.0.1"
		}

View on GitHub (pinned to c0390bff16)

Solutions

  1. Set the etcd endpoints (e.g. ETCD_ENDPOINTS=http://127.0.0.1:2379) in the connection config.
  2. Check that ConnectionString or Endpoints fields are populated if not using EtcdEndpoints.
  3. Verify the config file/env is actually loaded (no silent defaults overriding).
  4. Then confirm the endpoints are reachable, since empty vs. unreachable produce different errors.

Example fix

// before
connection := connectionParams{} // no endpoints
client, err := connect(connection) // No etcd endpoint configured
// after
connection := connectionParams{EtcdEndpoints: "http://127.0.0.1:2379"}
client, err := connect(connection)
Defensive patterns

Strategy: validation

Validate before calling

eps := connectionEndpoints(conn)
if len(eps) == 0 {
	return errors.New("no etcd endpoints: set EtcdEndpoints, Endpoints, or ConnectionString")
}
for _, ep := range eps {
	if u, err := url.Parse(ep); err != nil || u.Host == "" {
		return fmt.Errorf("invalid etcd endpoint %q", ep)
	}
}

Type guard

func hasEndpoints(conn connectionParams) bool {
	return firstNonBlank(conn.EtcdEndpoints, conn.Endpoints, conn.ConnectionString) != ""
}

Try / catch

client, err := connect(conn)
if err != nil {
	if strings.Contains(err.Error(), "No etcd endpoint configured") {
		return nil, fmt.Errorf("etcd endpoints missing: set ETCD_ENDPOINTS (e.g. http://127.0.0.1:2379): %w", err)
	}
	return nil, err
}

Prevention

When it happens

Trigger: connectionEndpoints finds no value in EtcdEndpoints, Endpoints, or ConnectionString (all blank), so probeClient iterates zero endpoints and falls through to this error; also reached if every attempt returned nil but lastFailure logic ran on an empty list.

Common situations: Missing ETCD_ENDPOINTS environment variable; empty connection string in config file; whitespace-only endpoint value; config struct built programmatically without setting endpoints.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/1ade2ef62ccaf81f. Report an issue: GitHub.