{"record":{"id":"fd7068781643d6a2","repo":"vitessio/vitess","slug":"failed-to-configure-stdin-v","errorCode":null,"errorMessage":"failed to configure stdin: %v","messagePattern":"failed to configure stdin: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/hook/hook.go","lineNumber":232,"sourceCode":"}\n\n// ExecuteAsWritePipe will execute the hook as in a Unix pipe,\n// directing output to the provided writer. It will return:\n// - an io.WriteCloser to write data to.\n// - a WaitFunc method to call to wait for the process to exit,\n// that returns stderr and the cmd.Wait() error.\n// - an error code and an error if anything fails.\nfunc (hook *Hook) ExecuteAsWritePipe(out io.Writer) (io.WriteCloser, 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\tin, err := cmd.StdinPipe()\n\tif err != nil {\n\t\treturn nil, nil, HOOK_GENERIC_ERROR, fmt.Errorf(\"failed to configure stdin: %v\", err)\n\t}\n\tcmd.Stdout = out\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 in, func() (string, error) {\n\t\terr := cmd.Wait()","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/hook/hook.go#L214-L250","documentation":"ExecuteAsWritePipe sets up the hook process's stdin as a pipe so the caller can write data to it. If cmd.StdinPipe() fails, the function aborts with HOOK_GENERIC_ERROR and this message. This is an OS-level pipe creation failure, occurring before the process starts.","triggerScenarios":"Calling hook.ExecuteAsWritePipe when the exec.Cmd StdinPipe call fails — practically always due to OS resource exhaustion (too many open file descriptors) or a closed/broken process setup.","commonSituations":"File descriptor leaks exhausting the process's ulimit -n; running in a constrained container with a low FD limit; long-running processes accumulating unclosed pipes.","solutions":["Check and raise the file descriptor limit (ulimit -n) for the process","Audit the calling process for leaked pipes/files not being closed and fix the leak","Inspect the wrapped %v error from StdinPipe for the exact OS error (e.g. EMFILE)"],"exampleFix":"// before: 'failed to configure stdin: too many open files'\n// after: raise FD limit for the service\nulimit -n 65536  # or set LimitNOFILE=65536 in systemd unit","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":"hr, w, status, err := h.ExecuteAsWritePipe(ctx, nil)\nif status == hook.HOOK_GENERIC_ERROR && strings.Contains(err.Error(), \"failed to configure stdin\") {\n    return fmt.Errorf(\"pipe setup failed (check ulimit -n): %v\", err)\n}","preventionTips":["Run services with a high LimitNOFILE (e.g. 65536)","Close pipes and io.ReadClosers returned by pipe-based hook calls promptly","Alert on file-descriptor usage in long-running vttablet processes"],"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"}