restic/restic · error
config file already exists
Error message
config file already exists
What it means
The REST backend's Create (used by 'restic init') first opens the repository, stats the config file at ConfigFile, and refuses to proceed when it already exists. This protects the existing repository from being overwritten by a second init.
Source
Thrown at internal/backend/rest/rest.go:95
cerr := resp.Body.Close()
// return first error
if err != nil {
return errors.Errorf("drain: %w", err)
}
return cerr
}
// Create creates a new REST on server configured in config.
func Create(ctx context.Context, cfg Config, rt http.RoundTripper, errorLog func(string, ...any)) (*Backend, error) {
be, err := Open(ctx, cfg, rt, errorLog)
if err != nil {
return nil, err
}
_, err = be.Stat(ctx, backend.Handle{Type: backend.ConfigFile})
if err == nil {
return nil, errors.New("config file already exists")
}
url := *cfg.URL
values := url.Query()
values.Set("create", "true")
url.RawQuery = values.Encode()
resp, err := be.client.Post(url.String(), "binary/octet-stream", strings.NewReader(""))
if err != nil {
return nil, err
}
if err := drainAndClose(resp); err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, &restError{backend.Handle{}, resp.StatusCode, resp.Status}View on GitHub (pinned to a80be1478a)
Solutions
- Skip init when the repository exists: run 'restic -r ... snapshots' first and only init when it reports a non-existent repo.
- If you truly want a fresh repo, remove or move the old one on the server (delete the config file or the whole prefix) before init.
- Verify the URL points at the intended, empty path and does not reuse an existing prefix.
Example fix
# before restic -r rest:http://server:8000/myrepo init # -> config file already exists # after restic -r rest:http://server:8000/myrepo snapshots || restic -r rest:http://server:8000/myrepo init
Defensive patterns
Strategy: validation
Validate before calling
// check existence before init
_, err := resticStatConfig(repoURL) // e.g. `restic -r <repo> cat config` equivalent
if err == nil {
return errors.New("repository already initialized; skipping init")
}
// safe to init Try / catch
err := be.Create(ctx, cfg, rt, nil)
if err != nil {
if strings.Contains(err.Error(), "config file already exists") {
// treat as idempotent success or surface a clear message
log.Printf("repository at %s already exists", cfg.URL)
return nil
}
return err
} Prevention
- Make init scripts idempotent: probe for the config file first.
- Never run init against a URL you cannot afford to lose; init refuses, but keep the habit.
When it happens
Trigger: Running 'restic -r rest:<url> init' when the REST server already has a 'config' file at the target; re-initializing after a partial earlier init; pointing the URL at an existing repo path/prefix.
Common situations: Scripts that run init unconditionally on every deployment; copying a repository to the server and then running init; wrong URL prefix so the request lands on an existing repository's namespace.
Related errors
- config file already exists
- invalid REST backend specification
- config file already exists
- invalid backend If the repository is in a local directory, y
- local backend not available
AI-assisted analysis of restic/restic@a80be1478a (2026-08-15).
Data as JSON: /api/errors/2a24c53eb8df7e0e.
Report an issue: GitHub.