{"record":{"id":"3d62f0faf2c1fec0","repo":"vitessio/vitess","slug":"failed-to-configure-stdout-v","errorCode":null,"errorMessage":"failed to configure stdout: %v","messagePattern":"failed to configure stdout: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/hook/hook.go","lineNumber":271,"sourceCode":"}\n\n// ExecuteAsReadPipe will execute the hook as in a Unix pipe, reading\n// from the provided reader. It will return:\n// - an io.Reader to read piped data from.\n// - a WaitFunc method to call to wait for the process to exit, that\n// returns stderr and the Wait() error.\n// - an error code and an error if anything fails.\nfunc (hook *Hook) ExecuteAsReadPipe(in io.Reader) (io.Reader, WaitFunc, int, error) {\n\t// Find the hook.\n\tcmd, status, err := hook.findHook(context.Background())\n\tif err != nil {\n\t\treturn nil, nil, status, err\n\t}\n\n\t// Configure the process's stdin, stdout, and stderr.\n\tout, err := cmd.StdoutPipe()\n\tif err != nil {\n\t\treturn nil, nil, HOOK_GENERIC_ERROR, fmt.Errorf(\"failed to configure stdout: %v\", err)\n\t}\n\tcmd.Stdin = in\n\tvar stderr strings.Builder\n\tcmd.Stderr = &stderr\n\n\t// Start the process.\n\terr = cmd.Start()\n\tif err != nil {\n\t\tstatus = HOOK_CANNOT_GET_EXIT_STATUS\n\t\tif cmd.ProcessState != nil {\n\t\t\tstatus = cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()\n\t\t}\n\t\treturn nil, nil, status, err\n\t}\n\n\t// And return\n\treturn out, func() (string, error) {\n\t\terr := cmd.Wait()","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/hook/hook.go#L253-L289","documentation":"ExecuteAsReadPipe sets up the hook process's stdout as a pipe so the caller can read its output. If cmd.StdoutPipe() fails, the function aborts with HOOK_GENERIC_ERROR and this message. Like the stdin variant, it is an OS pipe-creation failure before the process starts.","triggerScenarios":"Calling hook.ExecuteAsReadPipe when the exec.Cmd StdoutPipe call fails — typically OS file-descriptor exhaustion or invalid cmd state.","commonSituations":"FD exhaustion from leaked pipes in long-running processes; containers with low nofile limits; reusing an exec.Cmd whose pipes were already configured.","solutions":["Raise the file descriptor limit (ulimit -n / systemd LimitNOFILE)","Find and fix file-descriptor leaks (unclosed pipes/connections) in the calling process","Check the wrapped %v OS error from StdoutPipe for the precise cause"],"exampleFix":"// before: 'failed to configure stdout: too many open files'\n// after (docker)\ndocker run --ulimit nofile=65536:65536 ...","handlingStrategy":"fallback","validationCode":"if err := isFDHeadroomOK(4); err != nil {\n    return fmt.Errorf(\"not enough file descriptors for hook pipe: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"r, hr, status, err := h.ExecuteAsReadPipe(ctx, nil)\nif status == hook.HOOK_GENERIC_ERROR && strings.Contains(err.Error(), \"failed to configure stdout\") {\n    return fmt.Errorf(\"pipe setup failed (check ulimit -n): %v\", err)\n}","preventionTips":["Set nofile ulimits generously in containers and systemd units","Drain and close stdout pipes (read to EOF) to avoid leaks","Reuse hook execution paths that guarantee pipe cleanup via defer"],"tags":["hook","pipe","file-descriptors"],"backgroundTag":"too-many-open-files","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}