bitwarden/server · error · BadRequestException
Invalid response from Teams.
Error message
Invalid response from Teams.
What it means
Thrown during the Teams OAuth callback when teamsService.ObtainTokenViaOAuth returns null or empty after exchanging the authorization code with Microsoft. The token exchange failed — code expired, invalid, or Microsoft returned an error. BadRequestException returns HTTP 400.
Source
Thrown at src/Api/Dirt/Controllers/TeamsIntegrationController.cs:119
{
throw new NotFoundException();
}
var callbackUrl = Url.RouteUrl(
routeName: "TeamsIntegration_Create",
values: null,
protocol: currentContext.HttpContext.Request.Scheme,
host: currentContext.HttpContext.Request.Host.ToUriComponent()
);
if (string.IsNullOrEmpty(callbackUrl))
{
throw new BadRequestException("Unable to build callback Url");
}
var token = await teamsService.ObtainTokenViaOAuth(code, callbackUrl);
if (string.IsNullOrEmpty(token))
{
throw new BadRequestException("Invalid response from Teams.");
}
var teams = await teamsService.GetJoinedTeamsAsync(token);
if (!teams.Any())
{
throw new BadRequestException("No teams were found.");
}
var teamsIntegration = new TeamsIntegration(TenantId: teams[0].TenantId, Teams: teams);
integration.Configuration = JsonSerializer.Serialize(teamsIntegration);
await integrationRepository.UpsertAsync(integration);
var location = $"/organizations/{integration.OrganizationId}/integrations/{integration.Id}";
return Created(location, new OrganizationIntegrationResponseModel(integration));
}
[Route("integrations/teams/incoming")]View on GitHub (pinned to e93b962371)
Solutions
- Exchange the authorization code immediately after receiving it.
- Verify Azure AD app client_id/client_secret are correct in server configuration.
- Ensure the redirect URI registered in Azure AD matches the deployed callback URL exactly.
- Add retry logic for transient network failures during token exchange.
Example fix
// before
var token = await teamsService.ObtainTokenViaOAuth(code, callbackUrl);
if (string.IsNullOrEmpty(token)) throw new BadRequestException("Invalid response from Teams.");
// after — capture and surface the underlying error
var result = await teamsService.ObtainTokenViaOAuthAsync(code, callbackUrl);
if (!result.Success)
{
_logger.LogError("Teams token exchange failed: {Error}", result.ErrorDescription);
throw new BadRequestException($"Teams OAuth failed: {result.Error}");
} Defensive patterns
Strategy: retry
Validate before calling
// Pre-check Azure AD app configuration
if (string.IsNullOrWhiteSpace(_config["Teams:ClientId"]) ||
string.IsNullOrWhiteSpace(_config["Teams:ClientSecret"]) ||
string.IsNullOrWhiteSpace(_config["Teams:TenantId"]))
throw new InvalidOperationException("Teams OAuth credentials not configured."); Type guard
public static bool TeamsCredentialsConfigured(IConfiguration config) =>
!string.IsNullOrEmpty(config["Teams:ClientId"]) &&
!string.IsNullOrEmpty(config["Teams:ClientSecret"]); Try / catch
int attempts = 0;
string? token = null;
while (attempts < 3 && string.IsNullOrEmpty(token))
{
try { token = await _teamsService.ObtainTokenViaOAuth(code, callbackUrl); }
catch (Exception ex) when (attempts < 2) { _logger.LogWarning("Teams token attempt {N} failed: {Ex}", attempts, ex.Message); }
attempts++;
}
if (string.IsNullOrEmpty(token))
return BadRequest("Teams OAuth token exchange failed. Please retry the authorization flow."); Prevention
- Exchange the authorization code immediately after receiving the callback.
- Ensure the redirect URI in Azure AD matches the deployed callback URL exactly.
- Keep client secrets in secure configuration and rotate regularly.
- Add retry logic for transient Microsoft Graph outages.
When it happens
Trigger: OAuth callback with a stale/already-used/invalid authorization code; Microsoft Entra ID (Azure AD) app credentials misconfigured; redirect URI mismatch; network failure during server-to-Microsoft token exchange.
Common situations: User delays authorization so the code expires; duplicate callback consumption; Azure AD app client secret rotated but not updated in config; redirect URI registered in Azure portal doesn't match the deployed callback; transient Microsoft Graph API outage.
Related errors
- Invalid response from Slack.
- Unable to build callback Url
- There already exists a Teams integration for this organizati
- No teams were found.
- Unable to build callback Url
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/83634a30ed575615.
Report an issue: GitHub.