bitwarden/server · error · BadRequestException

Please provide a device type

Error message

Please provide a device type

What it means

Thrown by POST /devices/lost-trust when the device identifier is present but the device type is null in the request context. The endpoint logs a trust-loss event that includes the device type, so it refuses to proceed without it. Device type also comes from the device token claims set at registration time.

Source

Thrown at src/Api/Controllers/DevicesController.cs:328

    [HttpPost("lost-trust")]
    public void PostLostTrust()
    {
        var userId = _currentContext.UserId.GetValueOrDefault();
        if (userId == default)
        {
            throw new UnauthorizedAccessException();
        }

        var deviceId = _currentContext.DeviceIdentifier;
        if (deviceId == null)
        {
            throw new BadRequestException("Please provide a device identifier");
        }

        var deviceType = _currentContext.DeviceType;
        if (deviceType == null)
        {
            throw new BadRequestException("Please provide a device type");
        }

        _logger.LogError("User {id} has a device key, but didn't receive decryption keys for device {device} of type {deviceType}", userId,
            deviceId, deviceType);
    }

}

View on GitHub (pinned to e93b962371)

Solutions

  1. Re-register the device supplying a valid DeviceType so the device token includes the type claim.
  2. Ensure the client sends the DeviceType field when registering/reviving the device token.
  3. Refresh the access token after registration so the type claim is present.

Example fix

// before: device registered without a type, token has no device-type claim
//
// after: register with an explicit DeviceType (e.g. Mobile=0, Desktop=6, ...)
await deviceRepo.SaveAsync(new Device { Type = DeviceType.Android, Identifier = deviceId });
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the device token carries a type before calling lost-trust
const type = await getDeviceTypeClaim(accessToken);
if (type == null) {
  await reRegisterDeviceWithType(chosenDeviceType); // DeviceType.Android, etc.
  return;
}
await devicesApi.postLostTrust();

Type guard

function hasDeviceType(claims) { return claims?.devicetype != null; }

Try / catch

try {
  await devicesApi.postLostTrust();
} catch (e) {
  if (e.status === 400 && /device type/i.test(e.message)) {
    await reRegisterDeviceWithType(currentDeviceType);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling POST /devices/lost-trust with a device token that carries an identifier claim but no device-type claim. The earlier DeviceIdentifier check passes, then the DeviceType null check fires.

Common situations: Device registered/registered-token minted before the device-type claim was added; a token forged or partially built in tests; an old client that registered a device without sending a DeviceType and is now using a token lacking that claim.

Related errors


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