AdguardTeam/AdGuardHome · warning

auth: blocked for %s

Error message

auth: blocked for %s

What it means

Returned by the login HTTP handler when the per-IP rate limiter has blocked further login attempts. The client has exceeded the allowed number of failed authentications within the window, and the retry delay (with Retry-After header) is embedded in the message.

Source

Thrown at internal/home/authhttp.go:142

	if remoteIPStr, err = netutil.SplitHost(r.RemoteAddr); err != nil {
		web.writeErrorWithIP(
			ctx,
			fmt.Errorf("auth: getting remote address: %w", err),
			r,
			w,
			http.StatusBadRequest,
			r.RemoteAddr,
		)

		return
	}

	if rateLimiter := web.auth.rateLimiter; rateLimiter != nil {
		if left := rateLimiter.check(remoteIPStr); left > 0 {
			w.Header().Set(httphdr.RetryAfter, strconv.Itoa(int(left.Seconds())))
			web.writeErrorWithIP(
				ctx,
				fmt.Errorf("auth: blocked for %s", left),
				r,
				w,
				http.StatusTooManyRequests,
				remoteIPStr,
			)

			return
		}
	}

	ip, err := realIP(r)
	if err != nil {
		web.logger.ErrorContext(
			ctx,
			"getting real ip",
			"remote_ip", remoteIPStr,
			slogutil.KeyError, err,
		)

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Wait for the block to expire (the Retry-After header gives exact seconds)
  2. Fix the credential or auth backend causing repeated failures
  3. Ensure the correct X-Forwarded-For/trusted proxy config so NATed users aren't aggregated into one IP
  4. Increase or tune the rate limiter limits if legitimate traffic is being blocked

Example fix

// before: hammering login in a loop
for pw in passwords: login(pw)
// after: honor Retry-After
resp = login(pw)
if resp.status == 429: time.sleep(int(resp.headers['Retry-After']))
Defensive patterns

Strategy: retry

Try / catch

// Check HTTP 429 and Retry-After before retrying login
if resp.StatusCode == http.StatusTooManyRequests {
    wait, _ := strconv.Atoi(resp.Header.Get("Retry-After"))
    time.Sleep(time.Duration(wait) * time.Second)
}

Prevention

When it happens

Trigger: POST /login (handleLogin) from an IP that recently made too many attempts; web.auth.rateLimiter.check(remoteIPStr) returns a non-zero remaining block duration.

Common situations: Repeated wrong passwords, scripted/automated logins, several users behind one NAT/proxy IP, or testing login flows in a tight loop.

Related errors


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/1aab6ee977cc5d3b. Report an issue: GitHub.