{"record":{"id":"abf1f39b839c9649","repo":"bitwarden/server","slug":"unable-to-build-callback-url-abf1f3","errorCode":null,"errorMessage":"Unable to build callback Url","messagePattern":"Unable to build callback Url","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Api/Dirt/Controllers/TeamsIntegrationController.cs","lineNumber":43,"sourceCode":"    TimeProvider timeProvider) : Controller\n{\n    [HttpGet(\"{organizationId:guid}/integrations/teams/redirect\")]\n    public async Task<IActionResult> RedirectAsync(Guid organizationId)\n    {\n        if (!await currentContext.OrganizationOwner(organizationId))\n        {\n            throw new NotFoundException();\n        }\n\n        var callbackUrl = Url.RouteUrl(\n            routeName: \"TeamsIntegration_Create\",\n            values: null,\n            protocol: currentContext.HttpContext.Request.Scheme,\n            host: currentContext.HttpContext.Request.Host.ToUriComponent()\n        );\n        if (string.IsNullOrEmpty(callbackUrl))\n        {\n            throw new BadRequestException(\"Unable to build callback Url\");\n        }\n\n        var integrations = await integrationRepository.GetManyByOrganizationAsync(organizationId);\n        var integration = integrations.FirstOrDefault(i => i.Type == IntegrationType.Teams);\n\n        if (integration is null)\n        {\n            // No teams integration exists, create Initiated version\n            integration = await integrationRepository.CreateAsync(new OrganizationIntegration\n            {\n                OrganizationId = organizationId,\n                Type = IntegrationType.Teams,\n                Configuration = null,\n            });\n        }\n        else if (integration.Configuration is not null)\n        {\n            // A Completed (fully configured) Teams integration already exists, throw to prevent overriding","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/Dirt/Controllers/TeamsIntegrationController.cs#L25-L61","documentation":"Thrown during Teams OAuth initiation when Url.RouteUrl returns null/empty for route name 'TeamsIntegration_Create'. Identical pattern to the Slack callback-URL error but for the Microsoft Teams integration. BadRequestException returns HTTP 400, preventing the OAuth redirect from being generated.","triggerScenarios":"Initiating the Teams OAuth flow where the route 'TeamsIntegration_Create' is not registered or cannot be resolved. Also triggered when Request.Scheme/Host are unavailable behind a proxy.","commonSituations":"New deployment without forwarded-headers middleware; route renamed without updating the routeName parameter; reverse proxy stripping Host headers; environment-specific base path mismatch.","solutions":["Verify route 'TeamsIntegration_Create' is registered in the Teams controller.","Configure UseForwardedHeaders so Request.Host/Scheme are correct behind a reverse proxy.","Confirm routing middleware is properly ordered in the pipeline.","Provide a configurable BaseUrl fallback instead of relying solely on Url.RouteUrl."],"exampleFix":"// before\nvar callbackUrl = Url.RouteUrl(\"TeamsIntegration_Create\", values: null, protocol: ..., host: ...);\n\n// after — configuration-based fallback\nvar baseUri = _config[\"BaseUrl\"];\nvar callbackUrl = !string.IsNullOrEmpty(baseUri)\n    ? $\"{baseUri}/integrations/teams/callback\"\n    : Url.RouteUrl(\"TeamsIntegration_Create\", values: null, protocol: ..., host: ...);","handlingStrategy":"try-catch","validationCode":"// Integration test verifying route resolution\n[Fact]\npublic void TeamsCallbackRouteResolves()\n{\n    var url = _urlHelper.RouteUrl(\"TeamsIntegration_Create\");\n    Assert.False(string.IsNullOrEmpty(url));\n}","typeGuard":"public static bool TeamsCallbackUrlResolvable(IUrlHelper helper) =>\n    !string.IsNullOrEmpty(helper.RouteUrl(\"TeamsIntegration_Create\"));","tryCatchPattern":"try\n{\n    await _teamsService.InitiateOAuthAsync(orgId);\n}\ncatch (BadRequestException ex) when (ex.Message.Contains(\"callback Url\"))\n{\n    _logger.LogCritical(\"Teams callback route misconfigured.\");\n    return Problem(\"Teams integration is not properly configured on the server.\");\n}","preventionTips":["Configure UseForwardedHeaders in production behind any reverse proxy.","Write integration tests asserting named Teams routes resolve.","Provide a BaseUrl configuration fallback for callback URL construction."],"tags":["teams","oauth","routing","configuration","reverse-proxy","url-building","csharp","aspnet"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}