#1390·backrest

Editing an SFTP repository silently rewrites its flags: custom sftp.args (e.g. -F) and co-located flags are discarded

Author: alexdelpreteCreated Sep 21, 2026Updated Sep 21, 2026

Describe the bug

When an existing repository with an sftp: URI is opened with Edit, the modal rewrites the repository's flags as soon as it opens: every flag containing sftp.args is removed and replaced by a regenerated --option=sftp.args='-oBatchMode=yes ...', built only from the modal's identity-file / port / known_hosts fields.

Any other ssh argument inside sftp.args is silently discarded, for example -F /path/to/ssh_config (the ssh_config alias approach documented in the Backrest cookbook), and so is any other flag that happens to share the same array element.

As a result the edit modal (including Repo Config as JSON) does not show what is actually saved in config.json, and saving the repository, even for an unrelated change, would persist the loss and break the repository.

To Reproduce

  1. Have a working SFTP repository whose saved config looks like:
    json
    "uri": "sftp:MyAlias:/backup/restic-repo",
    "flags": [
      "--option sftp.args=\"-F /config/ssh_config\" --password-file \"/config/repo_password\""
    ]
    where MyAlias is a Host block in /config/ssh_config. Scheduled backup/forget/prune/check all work with this config.
  2. Open the repository and click Edit.
  3. Look at Repo Config as JSON, or click Test Configuration.

Expected behavior

When clicking Edit, the modal should load the repository exactly as it is stored in config.json and display it unchanged. What the edit form and Repo Config as JSON show must always match the saved configuration: opening the modal should never modify stored values on its own. Test Configuration should then run with the saved flags.

Actual behavior

The modal shows:

json
"flags": ["--option=sftp.args='-oBatchMode=yes'"]

-F /config/ssh_config and --password-file ... are gone, although they are still present in config.json. Test Configuration then fails with:

subprocess ssh: ssh: Could not resolve hostname myalias: Name does not resolve

In my case saving was rejected because the repository check failed with the rewritten flags, so config.json was left intact. In any setup where the rewritten flags still manage to connect, the save would succeed and the custom configuration would be lost without warning.

Cause

webui/src/features/repositories/AddRepoModal.tsx:

  • When a template is loaded, only -i, -p and -oUserKnownHostsFile are extracted from the existing sftp.args into the SFTP fields.
  • The useEffect depending on the URI and those fields then rebuilds the flags:
    typescript
    const newFlags = currentFlags.filter(
      (f: string) => f && !f.includes("sftp.args") && !f.includes("sftp.command"),
    );
    let sftpArgs = "-oBatchMode=yes";
    // + -i / -p / -oUserKnownHostsFile if set
    newFlags.push(`--option=sftp.args='${sftpArgs}'`);

Anything in sftp.args other than those three options is dropped, along with any other flag in the same array element.

Related

This is another symptom of the same behaviour as #1136: there, the regeneration wipes a newly added flag row when creating an SFTP repository; here, it silently rewrites the existing flags of an SFTP repository when editing it.

Suggested fix

The edit modal should parse the saved repository config and stay aligned with it, so that opening Edit never changes any value. sftp.args should only be regenerated when the user actually changes one of the SFTP fields, and even then unrecognised sftp.args content (and any other flags in the same element) should be preserved.

Workaround

Mount a directory as the container's /root/.ssh (config + keys) so ssh resolves the alias by default and no -F flag is needed.

Platform Info

  • Backrest v1.14.1 (Docker image garethgeorge/backrest:v1.14.1)