{"record":{"id":"e3b75b725de23bb8","repo":"crowdsecurity/crowdsec","slug":"appsec-is-down-w","errorCode":null,"errorMessage":"appsec is down: %w","messagePattern":"appsec is down: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/hubtest/hubtest_item.go","lineNumber":385,"sourceCode":"\tcrowdsecDaemon := exec.CommandContext(ctx, t.CrowdSecPath, cmdArgs...)\n\tcrowdsecDaemon.Dir = testPath\n\tcrowdsecDaemon.Env = []string{\"TESTDIR=\" + testPath, \"DATADIR=\" + t.RuntimeHubConfig.InstallDataDir, \"TZ=UTC\"}\n\n\tif err := crowdsecDaemon.Start(); err != nil {\n\t\treturn fmt.Errorf(\"starting crowdsec daemon: %w\", err)\n\t}\n\n\t// wait for the appsec port to be available\n\tif _, err = IsAlive(ctx, t.AppSecHost); err != nil {\n\t\tcrowdsecLog, err2 := os.ReadFile(crowdsecLogFile)\n\t\tif err2 != nil {\n\t\t\tlog.Errorf(\"unable to read crowdsec log file '%s': %s\", crowdsecLogFile, err)\n\t\t} else {\n\t\t\tlog.Errorf(\"crowdsec log file '%s'\", crowdsecLogFile)\n\t\t\tlog.Errorf(\"%s\\n\", string(crowdsecLog))\n\t\t}\n\n\t\treturn fmt.Errorf(\"appsec is down: %w\", err)\n\t}\n\n\t// check if the target is available\n\tnucleiTargetParsedURL, err := url.Parse(t.NucleiTargetHost)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to parse target '%s': %w\", t.NucleiTargetHost, err)\n\t}\n\n\tnucleiTargetHost := nucleiTargetParsedURL.Host\n\tif _, err = IsAlive(ctx, nucleiTargetHost); err != nil {\n\t\treturn fmt.Errorf(\"target is down: %w\", err)\n\t}\n\n\tnucleiConfig := NucleiConfig{\n\t\tPath:      \"nuclei\",\n\t\tOutputDir: t.RuntimePath,\n\t\tCmdLineOptions: []string{\n\t\t\t\"-ev\",    // allow variables from environment","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/hubtest/hubtest_item.go#L367-L403","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if err := waitReachable(appsecHost, 30*time.Second); err != nil { t.Skipf(\"appsec never came up: %v\", err) }","typeGuard":null,"tryCatchPattern":"if err := test.Run(ctx); err != nil {\n\tif strings.Contains(err.Error(), \"appsec is down\") {\n\t\tlog.Printf(\"dump crowdsec.log and config for diagnosis: %v\", err)\n\t}\n}","preventionTips":["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"],"tags":["appsec","startup","crowdsec","test-harness","healthcheck"],"backgroundTag":"connection-refused","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"}