ory/kratos · warning · wrapped sentinel error
ErrNetworkFailure
ErrNetworkFailure
Error message
ErrNetworkFailure wrapped: %s (network failure during HIBP range request)
What it means
The password validator checks leaked passwords via the HaveIBeenPwned range API. fetch performs the HTTP GET with a resilient HTTP client; if the request itself fails (connection error, timeout, DNS failure), the error is wrapped in ErrNetworkFailure with the underlying cause. This keeps the failure classifiable and subject to ignore_network_errors.
Solutions
- Set ignore_network_errors: true in the password HIBP config so registration proceeds when HIBP is unreachable.
- Verify outbound connectivity: curl https://api.pwnedpasswords.com/range/AAAAA from the server.
- Check proxy/firewall rules and allow egress to api.pwnedpasswords.com (HTTPS/443).
- Inspect the wrapped cause for the exact transport error (timeout vs refused vs DNS).
Defensive patterns
Strategy: fallback
Validate before calling
conn, err := net.DialTimeout("tcp", "api.pwnedpasswords.com:443", 2*time.Second)
if err != nil { /* egress to HIBP is blocked; enable ignore_network_errors */ } Try / catch
if errors.Is(err, strategy.ErrNetworkFailure) {
if cfg.IgnoreNetworkErrors { return allowed /* skip HIBP check */ }
return err
} Prevention
- Set ignore_network_errors: true for HIBP in availability-sensitive flows.
- Allow egress to api.pwnedpasswords.com in firewalls/proxies.
- Monitor HIBP reachability from the cluster.
- Keep the built-in prefix hash cache effective (long-lived instances).
When it happens
Trigger: Calling fetch (via validate) when retryablehttp request execution fails: api.pwnedpasswords.com unreachable, network outage, connection timeout (1s connection timeout), or proxy misconfiguration.
Common situations: Egress firewall blocking api.pwnedpasswords.com, DNS failures in restricted clusters, HIBP outages/rate limiting at connection level, or missing outbound internet access in air-gapped deployments.
Related errors
AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07).
Data as JSON: /api/errors/acb101980e2c35e4.
Report an issue: GitHub.
Appendix: source
Thrown at selfservice/strategy/password/validator.go:134
greatestLength = curr
}
lengths[i*len(b)+j] = curr
}
}
}
return greatestLength
}
func (s *DefaultPasswordValidator) fetch(ctx context.Context, hpw []byte, apiDNSName string) (int64, error) {
prefix := fmt.Sprintf("%X", hpw)[0:5]
loc := fmt.Sprintf("https://%s/range/%s", apiDNSName, prefix)
req, err := retryablehttp.NewRequestWithContext(ctx, "GET", loc, nil)
if err != nil {
return 0, err
}
res, err := s.reg.HTTPClient(ctx, httpx.ResilientClientWithConnectionTimeout(time.Second)).Do(req)
if err != nil {
return 0, errors.Wrapf(ErrNetworkFailure, "%s", err)
}
defer func() { _ = res.Body.Close() }()
if res.StatusCode != http.StatusOK {
return 0, errors.Wrapf(ErrUnexpectedStatusCode, "%d", res.StatusCode)
}
var thisCount int64
sc := bufio.NewScanner(res.Body)
for sc.Scan() {
row := sc.Text()
result := strings.Split(strings.TrimSpace(row), ":")
// We assume a count of 1. HIBP API sometimes responds without the
// colon, so we just assume that the leak count is one.
//
// See https://github.com/ory/kratos/issues/2145View on GitHub (pinned to b86338da04)