dagger/dagger · error
new client: %w
Error message
new client: %w
What it means
Wraps a failure of newBuildkitClient() at the end of startEngine — after the engine is provisioned, the client dials the engine's buildkit gRPC endpoint. Dial failures, TLS handshake errors, timeouts, or buildkit Info() RPC failures are wrapped here and abort the connect.
Source
Thrown at engine/client/client.go:505
CloudAuth: params.CloudAuth,
})
provisionCancel()
telemetry.EndWithCause(provisionSpan, &err)
if err != nil {
return err
}
ctx, span := Tracer(ctx).Start(ctx, "connecting to engine", telemetry.Encapsulate())
defer telemetry.EndWithCause(span, &rerr)
slog := slog.SpanLogger(ctx, InstrumentationLibrary)
slog.Debug("connecting", "runner", c.RunnerHost)
bkCtx, span := Tracer(ctx).Start(ctx, "creating client")
bkClient, bkInfo, err := newBuildkitClient(bkCtx, remote, c.connector)
telemetry.EndWithCause(span, &err)
if err != nil {
return fmt.Errorf("new client: %w", err)
}
c.bkClient = bkClient
c.bkVersion = bkInfo.BuildkitVersion.Version
c.bkName = bkInfo.BuildkitVersion.Revision
c.numCPU = bkInfo.SystemInfo.NumCPU
slog.Info("connected", "name", c.bkName, "client-version", engine.Version, "server-version", c.bkVersion)
imageBackend := c.ImageLoaderBackend
if imageBackend == nil {
imageBackend = driver.ImageLoader(ctx)
}
if imageBackend != nil {
imgloadCtx, span := Tracer(ctx).Start(ctx, "configuring image store")
c.imageLoader, err = imageBackend.Loader(imgloadCtx)
if err != nil {
err = fmt.Errorf("failed to get image loader: %w", err)
}View on GitHub (pinned to 82ba2681db)
Solutions
- Check the wrapped cause (errors.As for *url.Error or gRPC status) for dial vs. RPC failure
- Retry — races between engine readiness and dial usually resolve
- Verify the engine container is running and its port/socket is reachable
- Confirm TLS/proxy configuration matches the engine's expectations
Example fix
// before
client, err := dagger.Connect(ctx) // engine still booting, dial fails
// after
var client *dagger.Client
for i := 0; i < 5; i++ {
client, err = dagger.Connect(ctx)
if err == nil || !strings.Contains(fmt.Sprint(err), "new client") {
break
}
time.Sleep(2 * time.Second)
} Defensive patterns
Strategy: retry
Validate before calling
// confirm the engine endpoint is listening before dialing
conn, err := net.DialTimeout("tcp", engineAddr, 5*time.Second)
if err != nil {
return fmt.Errorf("engine not reachable at %s: %w", engineAddr, err)
}
conn.Close() Type guard
func isNewClientErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "new client")
} Try / catch
var client *dagger.Client
err := retry.Do(5, retry.Backoff(2*time.Second), func() error {
var e error
client, e = dagger.Connect(ctx)
if e != nil && isNewClientErr(e) { return e } // retry dial
return retry.Stop(e)
}) Prevention
- Pre-pull/start the engine and wait for readiness before connecting
- Check that the engine port/socket is exposed and reachable
- Keep TLS certs and clocks in sync to avoid handshake failures
- Bypass or configure proxies for gRPC traffic
When it happens
Trigger: Calling Connect/ConnectEngineToEngine when the buildkit gRPC dial to the started engine fails: engine not yet listening, wrong address, TLS misconfiguration, or the Info RPC times out.
Common situations: Slow engine startup exceeding dial timeout; engine container networking broken (host networking changes, port not exposed); proxy intercepting gRPC; clock skew breaking TLS.
Related errors
- remote is not a valid dagger server (expected %q, got %q)
- failed to create diff copy client: %w
- bridge from cidr: %w
- ensure iptables symlinks: %w
- install resolv.conf: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/ac047e1f4f8bf957.
Report an issue: GitHub.