bitwarden/server
Debugging
Where logs go
Every service is built on Bit.Core.Utilities.LoggerFactoryExtensions (src/Core/Utilities/LoggerFactoryExtensions.cs) which wires Serilog with two sinks by default:
- Console — visible when running
dotnet runor in containerdocker logs. - Sentry / Azure Application Insights — bound by
globalSettings.Sentry.DsnandglobalSettings.ApplicationInsights.InstrumentationKey. Only enabled when configured.
Self-hosted instances also write rolling files via the Logging section of appsettings.json. Log levels are tunable per category; production cloud uses Warning for the noisy categories (Microsoft.AspNetCore.*, Quartz, IdentityServer4.*) and Information for Bit.*.
Constants.BypassFiltersEventId (12482444) marks startup banners and other always-log lines so that overzealous category filters don't suppress them.
Common errors
| Symptom | Cause | Fix |
|---|---|---|
Unable to locate appsettings.<env>.json |
ASPNETCORE_ENVIRONMENT mismatch. |
Set ASPNETCORE_ENVIRONMENT=Development for local runs. |
IDX10501: Signature validation failed |
Identity signing cert missing / mismatched. | Regenerate via dev/create_certificates_*.sh; trust the dev cert. |
Cannot connect to mssql |
Compose mssql profile not running, or wrong password. |
docker compose --profile cloud up -d; check dev/.env MSSQL_PASSWORD. |
400 invalid_grant from /connect/token |
2FA required and not provided, or stale device_identifier. |
Inspect the response error_description; clear local clients' tokens. |
403 Forbidden from API after login |
JWT scope mismatch (e.g. mobile vs. web policies). | Confirm the client is calling the right Policies.* (see src/Api/Startup.cs AddPolicy calls). |
| Migrations fail mid-script | util/Migrator/DbScripts ordering or syntax error. |
dev/verify_migrations.ps1 will list every script and its dbo.Migration row. |
| Tests time out hitting the DB | Connection pool exhaustion in test parallelism. | Use the [Collection] collection fixtures rather than [Fact] if your test mutates DB state. |
Tracing a request end-to-end
Bitwarden does not enable distributed tracing out of the box. To trace a request manually:
- Identify the inbound request via the
RequestIdin the access log (SecurityHeadersMiddlewareandCurrentContextMiddlewarepopulateHttpContext.Items["CurrentContext"]). - The
ICurrentContextcarries the user / org IDs through scoped services. - The same
RequestIdcorrelates with downstreamEventService.LogCipherEventAsync(and friends), but those are persisted asynchronously via the events queue — so DB rows arrive indbo.Eventafter the response returns. - For push-related debugging, watch
Notificationslogs andHubHelpersfor the correspondingSendDeviceNotificationcall.
Identity / OAuth troubleshooting
- The Identity host exposes the OIDC discovery endpoint at
/.well-known/openid-configuration(when enabled).src/Identity/Startup.csconfigures the IdentityServer pipeline;src/Core/Auth/IdentityServer/contains every grant validator (ResourceOwnerPasswordValidator,WebAuthnLoginGrantValidator,SsoExtensionGrantValidator, …). - Increase the log level on
IdentityServer4.*andBit.Core.Auth.*inappsettings.Development.jsonto see grant decisions. - 2FA token providers live under
src/Core/Auth/Identity/TokenProviders/. Enable theBit.Core.Auth.Identity.TokenProviderscategory atDebugto see TOTP / WebAuthn / Email token validation.
Database deadlocks
The MariaDB / MySQL compose containers start with --innodb-print-all-deadlocks=ON so deadlock graphs land in container logs. SQL Server profiling requires connecting via SSMS / Azure Data Studio to the running container (localhost:1433).
Stripe webhook replay
The Billing service exposes Stripe / PayPal / Braintree webhook endpoints (src/Billing/Controllers/). For local testing, use the Stripe CLI:
stripe listen --forward-to http://localhost:47002/stripe/webhookSet globalSettings:stripe:apiKey and the webhookKey to your test-mode keys in user-secrets.
Debugging push notifications
Push goes through IPushNotificationService (src/Core/Platform/Push/). In dev:
- Enable SignalR push by setting
globalSettings:notifications:connectionStringto the Notifications app's URL. - Watch the
Notificationshost logs forHubHelpers"send" lines. - Mobile push uses Azure Notification Hub — check
globalSettings:pushHub:*. Self-hosted instances proxy through the Bitwarden cloud relay; if push isn't arriving, look atIRelayPushNotificationService.
Useful one-liners
# Tail a single service in compose
docker compose -f dev/docker-compose.yml --profile cloud logs -f mssql
# See what migrations are applied
docker compose -f dev/docker-compose.yml --profile cloud exec mssql /opt/mssql-tools/bin/sqlcmd \
-S localhost -U SA -P "$MSSQL_PASSWORD" -d vault_dev \
-Q "SELECT TOP 20 ScriptName FROM dbo.Migration ORDER BY ApplyDate DESC"
# Confirm cipher count for a user
sqlcmd -Q "SELECT COUNT(*) FROM dbo.Cipher WHERE UserId = '<guid>'"For routine support tasks the Admin host (src/Admin/) exposes a UI-driven set of debugging tools — see apps/admin.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.