bitwarden/server · error · BadRequestException
KeyConnectorKeyWrappedUserKey and AccountKeys must be suppli
Error message
KeyConnectorKeyWrappedUserKey and AccountKeys must be supplied.
What it means
Thrown by SetKeyConnectorKeyRequestModel.ToKeyConnectorKeysData() when either KeyConnectorKeyWrappedUserKey is null/empty or AccountKeys is null. This is a transitional validation (marked with a TODO referencing PM-27328 for removal) ensuring both fields are present when migrating or setting up Key Connector keys. BadRequestException returns HTTP 400.
Source
Thrown at src/Api/KeyManagement/Models/Requests/SetKeyConnectorKeyRequestModel.cs:110
// TODO removed with https://bitwarden.atlassian.net/browse/PM-27328
public User ToUser(User existingUser)
{
existingUser.Kdf = Kdf!.Value;
existingUser.KdfIterations = KdfIterations!.Value;
existingUser.KdfMemory = KdfMemory;
existingUser.KdfParallelism = KdfParallelism;
existingUser.Key = Key;
Keys!.ToUser(existingUser);
return existingUser;
}
public KeyConnectorKeysData ToKeyConnectorKeysData()
{
// TODO remove validation with https://bitwarden.atlassian.net/browse/PM-27328
if (string.IsNullOrEmpty(KeyConnectorKeyWrappedUserKey) || AccountKeys == null)
{
throw new BadRequestException("KeyConnectorKeyWrappedUserKey and AccountKeys must be supplied.");
}
return new KeyConnectorKeysData
{
KeyConnectorKeyWrappedUserKey = KeyConnectorKeyWrappedUserKey,
AccountKeys = AccountKeys,
OrgIdentifier = OrgIdentifier,
ContainedKeyId = KeyId.FromHexEncodedString(ContainedKeyId)
};
}
}
View on GitHub (pinned to e93b962371)
Solutions
- Ensure both KeyConnectorKeyWrappedUserKey and AccountKeys are populated in the request body.
- Use IsV2Request() to check before calling ToKeyConnectorKeysData() and handle V1 requests separately.
- Update the calling client to the latest version that sends both fields.
- Verify the Key Connector configuration flow is complete — the wrapped key and account keys are generated together during enrollment.
Example fix
// before
var data = request.ToKeyConnectorKeysData(); // throws if incomplete
// after — check V2 readiness first
if (!request.IsV2Request())
{
// handle V1 path or return a clear error
return BadRequest("This endpoint requires KeyConnectorKeyWrappedUserKey and AccountKeys.");
}
var data = request.ToKeyConnectorKeysData(); Defensive patterns
Strategy: validation
Validate before calling
// Validate request completeness before calling ToKeyConnectorKeysData
if (string.IsNullOrEmpty(request.KeyConnectorKeyWrappedUserKey) || request.AccountKeys == null)
return BadRequest("Both KeyConnectorKeyWrappedUserKey and AccountKeys must be supplied.");
var data = request.ToKeyConnectorKeysData(); Type guard
public static bool IsCompleteKeyConnectorRequest(SetKeyConnectorKeyRequestModel req) =>
req.IsV2Request(); // returns true only when both fields are present Try / catch
try
{
var data = request.ToKeyConnectorKeysData();
}
catch (BadRequestException ex) when (ex.Message.Contains("KeyConnectorKeyWrappedUserKey"))
{
return BadRequest("Key Connector setup requires both wrapped key and account keys. " +
"Ensure the client is running a version that supports Key Connector V2.");
} Prevention
- Call IsV2Request() before ToKeyConnectorKeysData() to branch V1 and V2 handling.
- Update client libraries to the latest version that sends both fields together.
- Complete the Key Connector enrollment flow in full — partial payloads are rejected.
When it happens
Trigger: POST/PUT to the key-connector key-setting endpoint (e.g., /users/key-connector) with a partial payload — KeyConnectorKeyWrappedUserKey present but AccountKeys missing, or vice versa. The IsV2Request() helper checks the same condition; this throw fires when ToKeyConnectorKeysData() is called on a non-V2 request.
Common situations: Client sends a V1-style request (only Key/Keys fields) to an endpoint that internally calls ToKeyConnectorKeysData(); key connector migration step skipped or partially completed; client library version mismatch where one field was added but not the other; org rolling out Key Connector with an outdated client.
Related errors
- All existing ciphers must be included in the rotation.
- Last synced date must be in the past.
- Only service accounts can sync secrets.
- You cannot import this much data at once, the limit is 1000
- A secret can only be in one project at a time.
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/07772f52695a3989.
Report an issue: GitHub.