nextcloud/all-in-one · error · InvalidSettingConfigurationException

Failed to rename ${tempFile} to ${DataConst::GetConfigFile()

Error message

Failed to rename ${tempFile} to ${DataConst::GetConfigFile()}

What it means

Thrown when rename() cannot move configuration.json.tmp over configuration.json after a successful temp write. The temp file is unlinked before throwing, so the previous config file remains intact. rename() failing at this point is almost always a cross-device or permission situation (EXDEV) or an immutable target.

Source

Thrown at php/src/Data/ConfigurationManager.php:859

        $content = json_encode($this->config, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR);
        $size = strlen($content) + 10240;
        if ($df !== false && (int)$df < $size) {
            throw new InvalidSettingConfigurationException(DataConst::GetDataDirectory() . " does not have enough space for writing the config file! Not writing it back!");
        }
        // Write to a temp file first to avoid truncating the config file if the
        // disk fills up mid-write. rename() is atomic on POSIX filesystems, so the
        // original config is never touched until the new content is fully on disk.
        $tempFile = DataConst::GetConfigFile() . '.tmp';
        if (file_put_contents($tempFile, $content) === false) {
            // The file probably wasn't created, but better check nonetheless.
            if (file_exists($tempFile)) {
                unlink($tempFile);
            }
            throw new InvalidSettingConfigurationException("Failed to write temporary config file: " . $tempFile);
        }
        if (!rename($tempFile, DataConst::GetConfigFile())) {
            unlink($tempFile);
            throw new InvalidSettingConfigurationException("Failed to rename " . $tempFile . " to " . DataConst::GetConfigFile());
        }
        $this->config = [];
    }

    private function getEnvironmentalVariableOrConfig(string $envVariableName, string $configName, string $defaultValue) : string {
        $envVariableOutput = getenv($envVariableName);
        $configValue = $this->get($configName, '');
        if ($envVariableOutput === false) {
            if ($configValue === '') {
                return $defaultValue;
            }
            return $configValue;
        }

        if (file_exists(DataConst::GetConfigFile())) {
            if ($envVariableOutput !== $configValue) {
                $this->set($configName, $envVariableOutput);
            }

View on GitHub (pinned to 6b788eec5e)

Solutions

  1. Mount the whole AIO data directory as a volume, not the single configuration.json file.
  2. Clear immutability if set: `chattr -i <host>/configuration.json`.
  3. Verify both files sit on the same filesystem and the directory is writable: `docker exec ... ls -la <data-dir>`.
  4. Remount the affected filesystem read-write and retry the settings change.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    $configurationManager->set('password', $newPassword);
} catch (\AIO\Data\InvalidSettingConfigurationException $e) {
    if (str_contains($e->getMessage(), 'Failed to rename')) {
        // temp file cleaned up, original config intact; check for single-file bind mounts / immutability
    }
}

Prevention

When it happens

Trigger: Committing a config change when the temp file and final config file end up on different mounts (e.g. configuration.json is a bind-mounted single file while .tmp is created on the container's local filesystem), when the target file/directory permissions block the replace, or when the filesystem is read-only/remounted ro.

Common situations: Bind-mounting configuration.json as a single file instead of its parent directory; immutable attribute (chattr +i) set on the config file during hardening; mount flipped to read-only after disk errors; overlayfs quirks with single-file bind mounts.

Related errors


AI-assisted analysis of nextcloud/all-in-one@6b788eec5e (2026-08-21). Data as JSON: /api/errors/75f50bf20f015aec. Report an issue: GitHub.