{"record":{"id":"f0cc5a216c75e64f","repo":"windmill-labs/windmill","slug":"could-not-create-initial-server-dir","errorCode":null,"errorMessage":"could not create initial server dir","messagePattern":"could not create initial server dir","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"backend/src/main.rs","lineNumber":1232,"sourceCode":"\n        send_logs_to_object_store(&conn, &hostname, &mode);\n\n        #[cfg(all(not(target_env = \"msvc\"), feature = \"jemalloc\"))]\n        if !worker_mode {\n            monitor_mem().await;\n        }\n\n        let addr = SocketAddr::from((server_bind_address, port));\n        let listener = tokio::net::TcpListener::bind(addr)\n            .await\n            .context(\"binding main windmill server\")?;\n\n        let (base_internal_tx, base_internal_rx) = tokio::sync::oneshot::channel::<String>();\n\n        DirBuilder::new()\n            .recursive(true)\n            .create(&*WINDMILL_DIR)\n            .expect(\"could not create initial server dir\");\n\n        #[cfg(feature = \"tantivy\")]\n        let should_index_jobs = mode == Mode::Indexer || mode_and_addons.indexer;\n\n        #[cfg(feature = \"tantivy\")]\n        if should_index_jobs {\n            if let Some(db) = conn.as_sql() {\n                reload_indexer_config(&db).await;\n            }\n        }\n\n        #[cfg(feature = \"tantivy\")]\n        let (index_reader, index_writer) = if should_index_jobs {\n            if let Some(db) = conn.as_sql() {\n                let mut indexer_rx = killpill_rx.resubscribe();\n\n                let (mut reader, mut writer) = (None, None);\n                tokio::select! {","sourceCodeStart":1214,"sourceCodeEnd":1250,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/src/main.rs#L1214-L1250","documentation":"At server startup, windmill_main creates the base WINDMILL_DIR directory (usually /tmp/windmill) recursively with tokio's DirBuilder and .expect()s success. If creation fails, the process panics with this message — the server cannot run without its base directory for job files, caches, and storage.","triggerScenarios":"Starting the windmill server binary where creating WINDMILL_DIR fails: the parent path is not writable by the server user, a non-directory file already occupies the path, read-only root filesystem, or restrictive container volume permissions.","commonSituations":"Docker/Kubernetes containers running as non-root with read-only or unwritable /tmp; systemd service with a hardened ProtectTmp/ReadOnlyPaths; WINDMILL_PATH/WINDMILL_DIR env pointing into a mounted file or missing volume.","solutions":["Check the panic's underlying io error in logs; verify the parent of WINDMILL_DIR (default /tmp/windmill) is writable by the server user: `ls -ld /tmp /tmp/windmill`.","Remove or rename any non-directory file occupying the path.","Point WINDMILL_PATH env at a writable location (e.g. a persistent volume mount) if /tmp is read-only.","Fix container/security-manager settings (drop read-only rootfs/ProtectTmp restrictions) or run as a user with write access."],"exampleFix":"// before (panic on failure)\nDirBuilder::new().recursive(true).create(&*WINDMILL_DIR)\n    .expect(\"could not create initial server dir\");\n// after (fail with context instead of bare panic)\nDirBuilder::new().recursive(true).create(&*WINDMILL_DIR)\n    .await\n    .unwrap_or_else(|e| panic!(\"could not create initial server dir {}: {e}\", *WINDMILL_DIR));","handlingStrategy":"validation","validationCode":"// Pre-flight: verify the base dir can be created before starting the server\nlet dir = std::path::Path::new(&*WINDMILL_DIR);\nif let Some(parent) = dir.parent() {\n    let md = std::fs::metadata(parent)?;\n    if md.permissions().readonly() {\n        return Err(format!(\"{} is not writable; set WINDMILL_PATH to a writable location\", parent.display()));\n    }\n}","typeGuard":null,"tryCatchPattern":"// Startup panics via expect; wrap pre-checks in your launcher/container entrypoint:\nmatch std::fs::create_dir_all(&*WINDMILL_DIR) {\n    Ok(_) => {},\n    Err(e) => {\n        eprintln!(\"could not create initial server dir {}: {e}\", *WINDMILL_DIR);\n        std::process::exit(1);\n    }\n}","preventionTips":["Ensure the server user can write to WINDMILL_DIR's parent (default /tmp)","Avoid read-only root filesystems or ProtectTmp hardening without a writable volume","Set WINDMILL_PATH to a dedicated writable persistent volume in containers","Pre-create the directory in the container image/entrypoint with correct ownership"],"tags":["filesystem","startup","permissions","panic","server"],"backgroundTag":"directory-creation-permission-denied","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"}