{"record":{"id":"3522aef7b8afdc13","repo":"crowdsecurity/crowdsec","slug":"could-not-get-journalctl-stdout-w","errorCode":null,"errorMessage":"could not get journalctl stdout: %w","messagePattern":"could not get journalctl stdout: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/acquisition/modules/journalctl/run.go","lineNumber":53,"sourceCode":"\t\targs = []string{\"--follow\", \"-n\", \"0\"}\n\t}\n\n\tif s.config.since != \"\" {\n\t\targs = append(args, \"--since\", s.config.since)\n\t}\n\n\treturn append(args, s.config.Filters...)\n}\n\nfunc (s *Source) runJournalCtl(ctx context.Context, out chan pipeline.Event) error {\n\tctx, cancel := context.WithCancel(ctx)\n\tdefer cancel()\n\n\tcmd := exec.CommandContext(ctx, journalctlCmd, s.getCommandArgs()...)\n\n\tstdout, err := cmd.StdoutPipe()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not get journalctl stdout: %w\", err)\n\t}\n\n\tstderr, err := cmd.StderrPipe()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not get journalctl stderr: %w\", err)\n\t}\n\n\tstderrChan := make(chan string)\n\tstdoutChan := make(chan string)\n\terrChan := make(chan error, 1)\n\n\ts.logger.WithField(\"command\", formatShellCommand(cmd.Args)).Info(\"Spawning process\")\n\n\terr = cmd.Start()\n\tif err != nil {\n\t\ts.logger.Errorf(\"Error spawning process: %s\", err)\n\t\treturn err\n\t}","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/acquisition/modules/journalctl/run.go#L35-L71","documentation":"runJournalCtl starts the journalctl binary via exec.CommandContext and asks for its stdout pipe before starting the process. StdoutPipe only fails in rare cases (the command already started, or OS pipe exhaustion), and the failure is wrapped with this message.","triggerScenarios":"Calling OneShot or Stream when cmd.StdoutPipe() returns a non-nil error — typically the command has already been started (Start/Run called before piping) or the OS cannot allocate a pipe (fd limit reached).","commonSituations":"Very high file-descriptor usage on a long-running crowdsec process (fd leak elsewhere); embedding/reusing the exec.Cmd incorrectly in a patched build.","solutions":["Check the wrapped inner error; if it says the command is already started, ensure StdoutPipe is called before Start.","Inspect the process fd usage (ls /proc/<pid>/fd | wc -l) and raise the ulimit if exhausted.","Restart crowdsec to clear leaked descriptors; investigate any fd leaks in custom modules.","Verify journalctl exists and is executable (though usually that surfaces later as exec failure, not pipe failure)."],"exampleFix":"// before\ncmd.Start()\nstdout, err := cmd.StdoutPipe() // fails: already started\n// after\nstdout, err := cmd.StdoutPipe()\nif err != nil { return err }\ncmd.Start()","handlingStrategy":"retry","validationCode":"// ensure fds are available before starting the source\nf, err := os.Open(os.DevNull)\nif err != nil { return errors.New(\"fd exhaustion likely\") }\nf.Close()","typeGuard":null,"tryCatchPattern":"if err := runJournalCtl(ctx); err != nil {\n    if strings.Contains(err.Error(), \"could not get journalctl stdout\") {\n        // backoff and retry; check fd limits if persistent\n    }\n}","preventionTips":["Raise ulimit -n for the crowdsec service unit","Monitor open fd counts on long-running processes","Never call exec.Cmd Start/Run before obtaining pipes in custom builds"],"tags":["go","exec","journalctl","pipe"],"backgroundTag":"file-open-failed","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}