crowdsecurity/crowdsec · error
journalctl exited with error: %w
Error message
journalctl exited with error: %w
What it means
After journalctl exits, runJournalCtl checks whether the parent context was canceled (normal shutdown, in which case 'signal: killed' is ignored and nil is returned). If the context was not canceled and the command exited non-zero, the exit error is wrapped with this message — meaning journalctl itself failed (bad args, no permission to read the journal, corrupted journal, etc.).
Source
Thrown at pkg/acquisition/modules/journalctl/run.go:126
}
}
return nil
})
cleanup := func() error {
// drain scanners
_ = g.Wait()
// reap journalctl, check status code
cmdErr := cmd.Wait()
// if the parent context was canceled, the journalctl error is likely "signal: killed" and we ignore that
if ctx.Err() != nil {
return nil //nolint:nilerr
}
if cmdErr != nil {
return fmt.Errorf("journalctl exited with error: %w", cmdErr)
}
// clean journalctl exit: should only happen in oneshot
return nil
}
for {
select {
case <-ctx.Done():
s.logger.Info("Datasource stopping")
return cleanup()
case stdoutLine, ok := <-stdoutChan:
if !ok {
s.logger.Debug("stdout channel is closed, stopping datasource")
return cleanup()
}
line := pipeline.Line{View on GitHub (pinned to 909b515798)
Solutions
- Run the same journalctl command manually (journalctl --output=json with your filters) to see its real error output.
- Add the crowdsec user to the systemd-journal (or adm) group: usermod -aG systemd-journal crowdsec.
- Fix invalid filter expressions — journalctl rejects unknown journal fields with a non-zero exit.
- Check journalctl binary presence/version: which journalctl; journalctl --version.
- If the error says 'signal: killed' during shutdown, it is benign — context cancellation handling already ignores that case.
Example fix
// before (as unprivileged user) s.Stream() // journalctl exits 1: permission denied // after // systemctl restart crowdsec (after adding user to systemd-journal group) s.Stream()
Defensive patterns
Strategy: try-catch
Validate before calling
// before enabling the source, verify the exact command works
out, err := exec.Command("journalctl", append([]string{"--output=json"}, args...)...).CombinedOutput()
if err != nil { return fmt.Errorf("journalctl precheck failed: %v: %s", err, out) } Try / catch
if err := src.Stream(); err != nil {
if strings.Contains(err.Error(), "journalctl exited with error") {
// run journalctl manually with same args; fix perms/filters
}
} Prevention
- Add the crowdsec user to the systemd-journal group
- Test filters with journalctl CLI before putting them in the DSN
- Pin journalctl/systemd versions and avoid mid-run upgrades
- Distinguish shutdown 'signal: killed' (benign) from real exit codes
When it happens
Trigger: OneShot or Stream runs journalctl which terminates with a non-zero exit code while crowdsec is not shutting down — e.g. invalid filters, user not in systemd-journal/adm group, or journald unavailable.
Common situations: Running crowdsec as a user lacking journal read permissions; typo in a filter causing journalctl to exit with 'unknown field'; system journal corruption; journalctl removed/upgraded mid-run.
Understand the failure class
Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.
Related errors
- could not get journalctl stdout: %w
- could not get journalctl stderr: %w
- unable to read %s : %s
- cannot parse: %s
- invalid DSN %s for journalctl source, must start with journa
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/b5c0ca8b0577ff29.
Report an issue: GitHub.