crowdsecurity/crowdsec · error
appsec is down: %w
Error message
appsec is down: %w
What it means
After starting the crowdsec daemon, RunWithNucleiTemplate polls IsAlive against the AppSec host; if the AppSec component never becomes reachable the daemon's log file is dumped and this error is returned. It means the AppSec engine failed to start or bind in time.
Source
Thrown at pkg/hubtest/hubtest_item.go:385
crowdsecDaemon := exec.CommandContext(ctx, t.CrowdSecPath, cmdArgs...)
crowdsecDaemon.Dir = testPath
crowdsecDaemon.Env = []string{"TESTDIR=" + testPath, "DATADIR=" + t.RuntimeHubConfig.InstallDataDir, "TZ=UTC"}
if err := crowdsecDaemon.Start(); err != nil {
return fmt.Errorf("starting crowdsec daemon: %w", err)
}
// wait for the appsec port to be available
if _, err = IsAlive(ctx, t.AppSecHost); err != nil {
crowdsecLog, err2 := os.ReadFile(crowdsecLogFile)
if err2 != nil {
log.Errorf("unable to read crowdsec log file '%s': %s", crowdsecLogFile, err)
} else {
log.Errorf("crowdsec log file '%s'", crowdsecLogFile)
log.Errorf("%s\n", string(crowdsecLog))
}
return fmt.Errorf("appsec is down: %w", err)
}
// check if the target is available
nucleiTargetParsedURL, err := url.Parse(t.NucleiTargetHost)
if err != nil {
return fmt.Errorf("unable to parse target '%s': %w", t.NucleiTargetHost, err)
}
nucleiTargetHost := nucleiTargetParsedURL.Host
if _, err = IsAlive(ctx, nucleiTargetHost); err != nil {
return fmt.Errorf("target is down: %w", err)
}
nucleiConfig := NucleiConfig{
Path: "nuclei",
OutputDir: t.RuntimePath,
CmdLineOptions: []string{
"-ev", // allow variables from environmentView on GitHub (pinned to 909b515798)
Solutions
- Read the printed crowdsec log file content in the error output — it shows why crowdsec/appsec died
- Kill leftover crowdsec processes from previous test runs holding the appsec port
- Verify the test config enables appsec and matches t.AppSecHost (host:port)
- Confirm appsec rules were installed (installAppsecRuleItem ran) before starting the daemon
Defensive patterns
Strategy: retry
Validate before calling
if err := waitReachable(appsecHost, 30*time.Second); err != nil { t.Skipf("appsec never came up: %v", err) } Try / catch
if err := test.Run(ctx); err != nil {
if strings.Contains(err.Error(), "appsec is down") {
log.Printf("dump crowdsec.log and config for diagnosis: %v", err)
}
} Prevention
- Kill leftover crowdsec processes before running the suite
- Ensure appsec is enabled and its port in config matches AppSecHost
- Install appsec rules before starting the daemon
When it happens
Trigger: IsAlive(ctx, t.AppSecHost) times out or errors after crowdsec starts: appsec not enabled in the test config, wrong port in appsec config, crowdsec crashed at startup, or slow startup exceeding the poll deadline.
Common situations: Port already in use by a leftover daemon from a previous run; appsec_configs/appsec rules not installed in the test DATADIR; config pointing appsec at a different address than AppSecHost; crowdsec panic visible in the dumped crowdsec.log.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- on_challenge hooks are only valid in-band, not under outofba
- no configuration paths provided
- while parsing '%s': %w
- get scenario in db: %w
- no appsec-config found for %s
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/e3b75b725de23bb8.
Report an issue: GitHub.