{"record":{"id":"d54bfb6592d84508","repo":"dagger/dagger","slug":"listen-for-nested-client-w","errorCode":null,"errorMessage":"listen for nested client: %w","messagePattern":"listen for nested client: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/engineutil/executor_spec.go","lineNumber":1113,"sourceCode":"\t\t}\n\t}\n\n\t// include overridden client version if it's set in the exec's env vars\n\tif version, ok := state.origEnvMap[\"_EXPERIMENTAL_DAGGER_VERSION\"]; ok {\n\t\tstate.nestedClientMetadata.ClientVersion = version\n\t}\n\n\tsrvCtx, srvCancel := context.WithCancelCause(ctx)\n\tstate.cleanups.Add(\"cancel session server\", cleanups.Infallible(func() {\n\t\tsrvCancel(errors.New(\"container cleanup\"))\n\t}))\n\tsrvPool := pool.New().WithContext(srvCtx).WithCancelOnError()\n\n\thttpListener, err := runInNetNS(ctx, state, func() (net.Listener, error) {\n\t\treturn net.Listen(\"tcp\", \"127.0.0.1:0\")\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"listen for nested client: %w\", err)\n\t}\n\tstate.cleanups.Add(\"close nested client listener\", cleanups.IgnoreErrs(httpListener.Close, net.ErrClosed))\n\n\ttcpAddr, ok := httpListener.Addr().(*net.TCPAddr)\n\tif !ok {\n\t\treturn fmt.Errorf(\"unexpected listener address type: %T\", httpListener.Addr())\n\t}\n\tstate.spec.Process.Env = append(state.spec.Process.Env, DaggerSessionPortEnv+\"=\"+strconv.Itoa(tcpAddr.Port))\n\tstate.spec.Process.Env = append(state.spec.Process.Env, DaggerEngineNumCPUEnv+\"=\"+strconv.Itoa(runtime.NumCPU()))\n\n\tprotocols := new(http.Protocols)\n\tprotocols.SetHTTP1(true)\n\tprotocols.SetUnencryptedHTTP2(true)\n\thttpSrv := &http.Server{\n\t\t// NOTE: no ReadHeaderTimeout (gosec G112) — see cmd/engine/main.go. On\n\t\t// Go >= 1.26.6 it becomes a hard lifetime cap on unencrypted HTTP/2\n\t\t// connections, which would kill every module function call that runs\n\t\t// longer than it.","sourceCodeStart":1095,"sourceCodeEnd":1131,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/engine/engineutil/executor_spec.go#L1095-L1131","documentation":"For execs hosting a nested Dagger client, setup runs net.Listen(\"tcp\", \"127.0.0.1:0\") inside the container's network namespace via runInNetNS. If listening fails (namespace entry failure, socket errors, resource limits), setup fails with 'listen for nested client'.","triggerScenarios":"runInNetNS(ctx, state, listenFn) returns an error: failure to enter the container netns, inability to bind a TCP socket on 127.0.0.1, or fd/resource exhaustion in the engine.","commonSituations":"Engine host under fd/memory pressure; network-namespace misconfiguration on the host; restrictive container runtimes or seccomp profiles blocking socket creation; running nested Dagger-in-Dagger in constrained environments.","solutions":["Retry the pipeline; transient netns/socket failures often clear under lighter load","Check host resource limits (ulimit -n, memory) on the Dagger engine host","Verify the container runtime allows socket creation inside netns (seccomp/apparmor profiles)","If using nested Dagger engines, test on the latest engine version and report persistent bind failures"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := dagDanger(func() error { return call.Func(ctx) })\nif err != nil && strings.Contains(err.Error(), \"listen for nested client\") {\n    time.Sleep(2 * time.Second)\n    return call.Func(ctx) // retry once after transient netns/fd failure\n}","preventionTips":["Monitor engine host fd/memory limits","Avoid seccomp/apparmor profiles that block loopback TCP binds in containers","Keep nested Dagger usage on current engine versions"],"tags":["network","listen","nested-client","netns"],"backgroundTag":"listen-tcp-failed","analyzedSha":"82ba2681dbe30d3547a1dc50ea495900ab5b6047","analyzedAt":"2026-09-05T07:21:37.930Z","contentChangedAt":"2026-09-05T07:21:37.930Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}