{"record":{"id":"b17a8fefda711e11","repo":"influxdata/influxdb","slug":"failed-to-rename-temp-directory-to-target","errorCode":null,"errorMessage":"Failed to rename temp directory to target","messagePattern":"Failed to rename temp directory to target","errorType":"exception","errorClass":"ProcessingEngineError::PluginError","httpStatus":null,"severity":"error","filePath":"influxdb3_processing_engine/src/lib.rs","lineNumber":1255,"sourceCode":"                    tokio::spawn(async move {\n                        let _ = async_fs::remove_dir_all(temp_clone).await;\n                    });\n                    ProcessingEngineError::PluginError(PluginError::AnyhowError(e))\n                })?;\n        }\n\n        let rename_result = async_fs::rename(&temp_path, &plugin_path).await;\n\n        if let Err(e) = rename_result {\n            // Rollback: restore old directory if it exists\n            if old_path.exists() {\n                let _ = async_fs::rename(&old_path, &plugin_path).await;\n            }\n            let _ = async_fs::remove_dir_all(&temp_path).await;\n\n            return Err(ProcessingEngineError::PluginError(\n                PluginError::AnyhowError(\n                    anyhow!(e).context(\"Failed to rename temp directory to target\"),\n                ),\n            ));\n        }\n\n        if old_path.exists() {\n            async_fs::remove_dir_all(&old_path)\n                .await\n                .context(\"Failed to delete old directory\")\n                .map_err(|e| ProcessingEngineError::PluginError(PluginError::AnyhowError(e)))?;\n        }\n\n        Ok(db_name)\n    }\n}\n\n#[derive(Debug)]\npub struct PluginFileInfo {\n    pub plugin_name: Arc<str>,","sourceCodeStart":1237,"sourceCodeEnd":1273,"githubUrl":"https://github.com/influxdata/influxdb/blob/d28e26e048401c53cbb98cf2d6ab0cf1e98048ca/influxdb3_processing_engine/src/lib.rs#L1237-L1273","documentation":"replace_plugin_directory() performs an atomic swap: new files go to a '.tmp' directory, the current one is moved to '.old', then async_fs::rename(tmp -> target) runs. If that final rename fails, the engine rolls back (restores '.old' to the target, deletes the temp dir) and returns the filesystem error with context 'Failed to rename temp directory to target'. The rollback means the previously installed plugin version is preserved.","triggerScenarios":"rename(2) failing on the plugin directory: permission denied, the plugin dir living on a filesystem with broken rename semantics (some NFS/SMB mounts), the target held open by another process (Windows AV/indexers/another server instance), or disk/inode exhaustion during the swap.","commonSituations":"--plugin-dir on a network volume inside Kubernetes; two server processes pointed at the same plugin dir; permission changes after the server started; antivirus or backup jobs scanning the plugin dir mid-swap.","solutions":["Check the underlying IO error and the plugin dir: permissions (writable by the server user) and free space","Move --plugin-dir to a local POSIX filesystem; network mounts often lack reliable atomic rename","Ensure exactly one server instance writes to the plugin dir and no external process locks files inside it","Retry the replace after remediation — the rollback restored the old version, so state is consistent"],"exampleFix":"# before: plugin dir on an NFS volume with unreliable rename\ninfluxdb3 serve --plugin-dir /mnt/nfs/plugins ...\n\n# after: local writable volume\ninfluxdb3 serve --plugin-dir /var/lib/influxdb3/plugins ...","handlingStrategy":"retry","validationCode":"# preflight before a plugin update: writable dir, local FS, free space\nDF=$(df -P /var/lib/influxdb3/plugins | awk 'NR==2 {print $4}')\ntest -w /var/lib/influxdb3/plugins && [ \"$DF\" -gt 1048576 ] \\\n  || { echo \"plugin dir not writable or low on space\" >&2; exit 1; }","typeGuard":null,"tryCatchPattern":"match engine.replace_plugin_directory(name, files).await {\n    Err(e) if e.to_string().contains(\"Failed to rename temp directory\") => {\n        // engine rolled back to the previous version; fix fs issue then retry once\n        log::warn!(\"plugin replace rolled back: {e}\");\n        engine.replace_plugin_directory(name, files).await?\n    }\n    other => other?,\n}","preventionTips":["Put --plugin-dir on a local POSIX filesystem, not NFS/SMB","Allow exactly one writer (server instance) to the plugin dir; keep AV/backup scans away from it","Monitor free space and permissions on the plugin volume","Rely on the built-in rollback: after a rename failure the old plugin version is restored — verify it still loads, then retry"],"tags":["influxdb","processing-engine","plugins","filesystem","rename","atomic-update"],"backgroundTag":"file-rename-failure","analyzedSha":"d28e26e048401c53cbb98cf2d6ab0cf1e98048ca","analyzedAt":"2026-08-16T19:53:34.623Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}