{"record":{"id":"8f9172e44e5f75b7","repo":"windmill-labs/windmill","slug":"server-mode-requires-a-database-connection","errorCode":null,"errorMessage":"Server mode requires a database connection","messagePattern":"Server mode requires a database connection","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"backend/src/main.rs","lineNumber":1155,"sourceCode":"        if !valid_key && !server_mode {\n            tracing::error!(\"Invalid license key, workers require a valid license key\");\n        }\n        if server_mode || mcp_mode {\n            if let Some(db) = conn.as_sql() {\n                // only force renewal if invalid but not empty (= expired)\n                let renewed_now = maybe_renew_license_key_on_start(\n                    &HTTP_CLIENT,\n                    &db,\n                    !valid_key && !LICENSE_KEY_ID.load().is_empty(),\n                )\n                .await;\n                if renewed_now {\n                    if let Err(err) = reload_license_key(&conn).await {\n                        tracing::error!(\"Failed to reload license key: {err:#}\");\n                    }\n                }\n            } else {\n                panic!(\"Server mode requires a database connection\");\n            }\n        }\n    }\n\n    if server_mode || worker_mode || indexer_mode || mcp_mode {\n        let port_var = std::env::var(\"PORT\")\n            .or_else(|_| std::env::var(\"BACKEND_PORT\"))\n            .ok()\n            .and_then(|x| x.parse().ok());\n\n        let port = if server_mode || indexer_mode || mcp_mode {\n            port_var.unwrap_or(DEFAULT_PORT as u16)\n        } else {\n            port_var.unwrap_or(0)\n        };\n\n        let default_base_internal_url = format!(\"http://localhost:{}\", port.to_string());\n        // since it's only on server mode, the port is statically defined","sourceCodeStart":1137,"sourceCodeEnd":1173,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/src/main.rs#L1137-L1173","documentation":"Windmill's main panics when the binary runs in server mode but no database connection (`conn`) could be established/passed. Server mode fundamentally requires a Postgres connection; proceeding without one is treated as an unrecoverable startup misconfiguration rather than a runtime error.","triggerScenarios":"Starting the windmill binary with MODE=server (default) while `DATABASE_URL` is missing/unreachable, or the connection setup failed so `conn` is None at the check in windmill_main.","commonSituations":"Forgot to set DATABASE_URL; Postgres not running or wrong host/port/credentials; DB env var typo; running the binary in a container without the DB service linked.","solutions":["Set a correct DATABASE_URL env var (e.g. postgres://user:pass@host:5432/windmill)","Verify Postgres is running and reachable from the binary (psql to the same URL)","If you intentionally want no DB, run a non-server mode (worker with queue access via separate config, or agent mode in EE)","Check startup logs just above the panic for the underlying connection error (auth, DNS, TLS)"],"exampleFix":"// before\nMODE=server   # no DATABASE_URL\n// after\nexport DATABASE_URL=postgres://postgres:changeme@localhost:5432/windmill\n./windmill server","handlingStrategy":"validation","validationCode":"// shell check before starting the server\nif [ \"$MODE\" != \"agent\" ] && [ -z \"$DATABASE_URL\" ]; then\n  echo \"FATAL: server/worker mode requires DATABASE_URL\" >&2; exit 1\nfi\n# plus a reachability check:\npsql \"$DATABASE_URL\" -c 'select 1' || { echo 'DB unreachable'; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate DATABASE_URL in your entrypoint/startup script before exec'ing the binary","Run health checks on Postgres in orchestrator readiness probes","Keep DB credentials in secret management, injected consistently into containers","Read startup logs above the panic — the real connection error (auth/DNS/TLS) is printed there"],"tags":["database","postgres","configuration","startup"],"backgroundTag":"missing-database-url","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}