crowdsecurity/crowdsec · error

unable to get challenge page: %w

Error message

unable to get challenge page: %w

What it means

When a client must solve a proof-of-work challenge, the engine asks ChallengeRuntime.GetChallengePage for the HTML challenge page at the required difficulty. If generating/fetching that page fails (template, WASM challenge runtime, or internal state problem), this error aborts sending the challenge and the request handling returns an error.

Source

Thrown at pkg/appsec/appsec.go:1665

		return nil
	}

	target := w.ChallengeRuntime.Difficulty()
	if state.ChallengeDifficulty != nil {
		target = *state.ChallengeDifficulty
	}

	if state.Fingerprint != nil && state.CookiePowDifficulty >= target {
		w.Logger.Debugf("client already proved difficulty %d >= target %d, skipping challenge issue",
			state.CookiePowDifficulty, target)
		return nil
	}

	w.Logger.Debugf("sending challenge at difficulty %d (client proved %d)", target, state.CookiePowDifficulty)

	challengePage, err := w.ChallengeRuntime.GetChallengePage(ctx, request.HTTPRequest.UserAgent(), target)
	if err != nil {
		return fmt.Errorf("unable to get challenge page: %w", err)
	}

	if err := w.setChallengeResponse(state, http.StatusOK, challengePage, map[string]string{"Content-Type": "text/html", "Cache-Control": "no-cache, no-store"}, nil); err != nil {
		return err
	}

	w.emitChallenge(state, request, ChallengeEventInfo{
		Reason:      ChallengeReasonRequested,
		Difficulty:  target,
		Fingerprint: state.Fingerprint,
		Score:       state.RequestScore.Total(),
		ScoreDetail: state.RequestScore.String(),
	})

	return nil
}

// RejectSubmission flags the in-flight challenge submission so the

View on GitHub (pinned to 909b515798)

Solutions

  1. Check crowdsec logs for the wrapped error to see whether the challenge runtime failed to initialize at startup
  2. Verify the appsec config's bans/challenge settings (challenge difficulty, allowed targets) are valid
  3. Restart crowdsec to reinitialize the challenge runtime
  4. Ensure the data directory with challenge assets is present and readable
  5. If it persists after a clean config, report as a bug with the wrapped error
Defensive patterns

Strategy: try-catch

Validate before calling

if w.ChallengeRuntime == nil {
    return errors.New("challenge runtime not initialized")
}

Try / catch

page, err := w.ChallengeRuntime.GetChallengePage(ctx, ua, target)
if err != nil {
    log.Errorf("challenge page unavailable, serving plain 403 instead: %v", err)
    http.Error(rw, "Forbidden", http.StatusForbidden)
    return
}

Prevention

When it happens

Trigger: GetChallengePage(ctx, userAgent, target) returning an error: challenge runtime not initialized properly, difficulty target invalid, template rendering failure, or missing embedded challenge assets.

Common situations: Bans/challenges enabled without required data dir assets; misconfigured challenge difficulty; internal bug or upgrade left challenge runtime in a bad state.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/29d340dd748615f0. Report an issue: GitHub.