crowdsecurity/crowdsec · error

loki is not ready: %w

Error message

loki is not ready: %w

What it means

Before one-shot acquisition, the Loki source probes the server's /ready endpoint within the WaitForReady window (skipped only when NoReadyCheck is set). Any failure from Client.Ready — connection refused, 503 not-ready, timeout — is wrapped as 'loki is not ready'.

Source

Thrown at pkg/acquisition/modules/loki/run.go:30

	"github.com/prometheus/client_golang/prometheus"
	tomb "gopkg.in/tomb.v2"

	"github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/loki/internal/lokiclient"
	"github.com/crowdsecurity/crowdsec/pkg/metrics"
	"github.com/crowdsecurity/crowdsec/pkg/pipeline"
)

// OneShotAcquisition reads a set of file and returns when done
func (l *Source) OneShotAcquisition(ctx context.Context, out chan pipeline.Event, t *tomb.Tomb) error {
	l.logger.Debug("Loki one shot acquisition")
	l.Client.SetTomb(t)

	if !l.Config.NoReadyCheck {
		readyCtx, readyCancel := context.WithTimeout(ctx, l.Config.WaitForReady)
		defer readyCancel()

		if err := l.Client.Ready(readyCtx); err != nil {
			return fmt.Errorf("loki is not ready: %w", err)
		}
	}

	lokiCtx, cancel := context.WithCancel(ctx)
	defer cancel()

	c := l.Client.QueryRange(lokiCtx, false)

	for {
		select {
		case <-t.Dying():
			l.logger.Debug("Loki one shot acquisition stopped")
			return nil
		case resp, ok := <-c:
			if !ok {
				l.logger.Info("Loki acquisition done, chan closed")
				return nil
			}

View on GitHub (pinned to 909b515798)

Solutions

  1. Confirm Loki is actually up: curl http://<loki-host>:3100/ready until it returns 200 'ready'
  2. Increase wait_for_ready in the Loki acquisition config
  3. Fix the Loki URL/host/port in the acquisition yaml or DSN
  4. If the probe is intentionally unwanted, set no_ready_check: true (errors will then surface later at read time)

Example fix

// before (acquisition yaml)
wait_for_ready: 1s
// after
wait_for_ready: 30s
Defensive patterns

Strategy: retry

Validate before calling

func lokiReady(baseURL string) error {
    for i := 0; i < 30; i++ {
        resp, err := http.Get(baseURL + "/ready")
        if err == nil && resp.StatusCode == 200 {
            resp.Body.Close()
            return nil
        }
        if resp != nil { resp.Body.Close() }
        time.Sleep(2 * time.Second)
    }
    return errors.New("loki /ready never returned 200")
}

Try / catch

if err := src.OneShotAcquisition(ctx); err != nil {
    if strings.Contains(err.Error(), "loki is not ready") {
        // re-check /ready with backoff, then retry acquisition
    }
    return err
}

Prevention

When it happens

Trigger: Calling OneShotAcquisition after Configure/ConfigureByDSN when the Loki URL points at a host that is down, still booting, or answering /ready with a non-200 within wait_for_ready.

Common situations: crowdsec started by orchestration before Loki finishes booting; wrong Loki host/port in the DSN; wait_for_ready shorter than Loki's cold-start time.

Related errors


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