bitwarden/server · error · BadRequestException

HaveIBeenPwned API key not set.

Error message

HaveIBeenPwned API key not set.

What it means

Thrown as BadRequestException by the HaveIBeenPwned breach endpoint when GlobalSettings.HibpApiKey has no value. The controller refuses to proxy any HIBP request without a configured key because the upstream API requires one; SettingHasValue returns false for null/empty/whitespace.

Source

Thrown at src/Api/Dirt/Controllers/HibpController.cs:55

        GlobalSettings globalSettings)
    {
        _userService = userService;
        _currentContext = currentContext;
        _globalSettings = globalSettings;
        _userAgent = _globalSettings.SelfHosted ? "Bitwarden Self-Hosted" : "Bitwarden";
    }

    [HttpGet("breach")]
    public async Task<IActionResult> Get(string username)
    {
        return await SendAsync(WebUtility.UrlEncode(username), true);
    }

    private async Task<IActionResult> SendAsync(string username, bool retry)
    {
        if (!CoreHelpers.SettingHasValue(_globalSettings.HibpApiKey))
        {
            throw new BadRequestException("HaveIBeenPwned API key not set.");
        }
        var request = new HttpRequestMessage(HttpMethod.Get, string.Format(HibpBreachApi, username));
        request.Headers.Add("hibp-api-key", _globalSettings.HibpApiKey);
        request.Headers.Add("hibp-client-id", GetClientId());
        request.Headers.Add("User-Agent", _userAgent);
        var response = await _httpClient.SendAsync(request);
        if (response.IsSuccessStatusCode)
        {
            var data = await response.Content.ReadAsStringAsync();
            return Content(data, "application/json");
        }
        else if (response.StatusCode == HttpStatusCode.NotFound)
        {
            /* 12/1/2025 - Per the HIBP API, If the domain does not have any email addresses in any breaches, 
               an HTTP 404 response will be returned. API also specifies that "404 Not found is the account could 
               not be found and has therefore not been pwned". Per REST semantics we will return 200 OK with empty array. */
            return Content("[]", "application/json");
        }

View on GitHub (pinned to e93b962371)

Solutions

  1. Set the HibpApiKey global setting (environment variable / appsettings) to a valid HIBP API key.
  2. Restart/reload the app so the config is picked up.
  3. Obtain a key from HaveIBeenPwned if one is not held.
  4. If HIBP is intentionally disabled, prevent the client from calling the breach endpoint.

Example fix

// before: no key configured
//   globalSettings:HibpApiKey = null  -> GET /hibp/breach -> 400
//
// after: set the environment variable and restart
//   HibpApiKey__value is configured in appsettings or env:
export globalSettings__hibpApiKey="<your-hibp-key>"
# then restart the API process
Defensive patterns

Strategy: validation

Validate before calling

// Verify the HIBP key is configured before exposing the breach endpoint to users
const hasKey = settingHasValue(globalSettings.hibpApiKey);
if (!hasKey) {
  // disable the breach-check UI or show 'feature unavailable'
  return unavailable();
}
await getBreaches(username);

Type guard

function settingHasValue(v) { return typeof v === 'string' && v.trim().length > 0; }

Try / catch

try {
  await getBreaches(username);
} catch (e) {
  if (e.status === 400 && /hibp.*api key/i.test(e.message)) {
    // surface a server-config error to operators, not end users
    notifyOpsToSetHibpKey();
  } else throw e;
}

Prevention

When it happens

Trigger: Any GET /hibp/breach?username=... call when HibpApiKey is unset/empty/whitespace in the server's global settings (environment/config). It is a config error surfaced to the caller as 400.

Common situations: New self-hosted deployment that never configured the HIBP key; key removed from environment in an upgrade; key set on the wrong environment variable name; cloud-to-self-host migration missing the key.

Related errors


AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13). Data as JSON: /api/errors/5d3f993eb575ed20. Report an issue: GitHub.