Open-Source Wikis

/

Bitwarden Server

/

How to contribute

/

Debugging

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:

  1. Console — visible when running dotnet run or in container docker logs.
  2. Sentry / Azure Application Insights — bound by globalSettings.Sentry.Dsn and globalSettings.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:

  1. Identify the inbound request via the RequestId in the access log (SecurityHeadersMiddleware and CurrentContextMiddleware populate HttpContext.Items["CurrentContext"]).
  2. The ICurrentContext carries the user / org IDs through scoped services.
  3. The same RequestId correlates with downstream EventService.LogCipherEventAsync (and friends), but those are persisted asynchronously via the events queue — so DB rows arrive in dbo.Event after the response returns.
  4. For push-related debugging, watch Notifications logs and HubHelpers for the corresponding SendDeviceNotification call.

Identity / OAuth troubleshooting

  • The Identity host exposes the OIDC discovery endpoint at /.well-known/openid-configuration (when enabled). src/Identity/Startup.cs configures the IdentityServer pipeline; src/Core/Auth/IdentityServer/ contains every grant validator (ResourceOwnerPasswordValidator, WebAuthnLoginGrantValidator, SsoExtensionGrantValidator, …).
  • Increase the log level on IdentityServer4.* and Bit.Core.Auth.* in appsettings.Development.json to see grant decisions.
  • 2FA token providers live under src/Core/Auth/Identity/TokenProviders/. Enable the Bit.Core.Auth.Identity.TokenProviders category at Debug to 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/webhook

Set 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:

  1. Enable SignalR push by setting globalSettings:notifications:connectionString to the Notifications app's URL.
  2. Watch the Notifications host logs for HubHelpers "send" lines.
  3. Mobile push uses Azure Notification Hub — check globalSettings:pushHub:*. Self-hosted instances proxy through the Bitwarden cloud relay; if push isn't arriving, look at IRelayPushNotificationService.

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.

Debugging – Bitwarden Server wiki | Factory