> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cloudstic.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Repository Compatibility

> What Cloudstic guarantees about reading old repositories and refusing repositories that are too new

Cloudstic is a backup tool, and restoring an old backup is not a nice-to-have — it is the product. A repository written years ago, by a version of Cloudstic nobody runs any more, must still restore today. This page explains the compatibility guarantee behind that promise, and what happens if you ever point an older Cloudstic build at a newer repository.

## Backward compatibility is permanent

**Any repository written by any released version of Cloudstic remains readable by every later version, forever.**

There is no deprecation window and no expiry date on this guarantee. Support for old repository layouts may be refactored or made faster internally, but it is never removed, and it never changes behavior. Concretely, this means `list`, `ls`, `check`, `cat`, `diff`, and `restore` all keep working against a repository no matter how old it is. Writing to an old repository (`backup`, `prune`, `forget`) is also supported, and may upgrade parts of the repository's on-disk format in place as a side effect.

<Note>
  You never need to run a migration command. Opening an old repository with a current build of Cloudstic just works.
</Note>

## Newer repositories, older builds

The reverse direction is not guaranteed: an older Cloudstic build is not guaranteed to fully understand a repository written by a newer one. Formats do change over time, and that's expected.

What Cloudstic guarantees instead is that this situation **fails safely**. An older build that encounters a repository format it doesn't recognize will refuse to operate on it, rather than silently misreading it. If you try, you'll see an error like:

```text theme={null}
repository format version 2 is newer than this build supports (up to 1):
upgrade cloudstic to work with this repository
```

**The fix is simple: upgrade Cloudstic.** Once you're running a build that supports the repository's format, everything works normally again.

<Warning>
  Never work around this error by rolling back a repository or hand-editing its `config` marker. The version gate exists to stop an operation from destroying data it can't fully see — bypassing it removes that protection.
</Warning>

## Why the gate matters: don't confuse "unreadable" with "empty"

The reason Cloudstic refuses outright, instead of doing its best with what it can parse, is a specific and serious failure mode: treating an index that failed to load as if it were an empty index.

An empty index legitimately means "nothing is referenced." But a *failed-to-load* index means "we don't know what's referenced" — and those are very different statements. If a garbage collector (`prune`) ever confused the two, it would see "nothing is referenced" and delete everything, including live, healthy data it simply failed to read.

This isn't hypothetical. An early Cloudstic release, pointed at a repository containing a data structure it couldn't decode, reported `0 snapshots` with no error — and running `prune` against it deleted the repository's packfiles. That incident is why the version gate exists: any build that cannot fully understand a repository now refuses to touch it at all, rather than guessing.

## How repositories actually get upgraded

There is no separate "migrate this repository" command, and no moment where a repository becomes "fully upgraded." Upgrades happen **in place and opportunistically**, as a byproduct of normal write operations:

* The first time a newer Cloudstic build runs `backup`, `prune`, or `forget` against an older repository, it may write some data in the newer format alongside data still in the old format.
* Only the parts of the repository actually touched by that write get upgraded. Everything else stays as it was.

That means a long-lived, frequently-used repository is, indefinitely, a **mixture of format eras** — and that's the intended steady state, not a transitional phase you need to "finish." Because backward compatibility never expires, nothing ever needs that mixture to fully resolve.

<Tip>
  If you run a fleet of machines against a shared repository, keep every machine's Cloudstic build reasonably current. A machine that writes to the repository can raise its recorded format version — which is a real, useful signal that the repository now contains something newer builds understand and older ones might not. Letting one machine lag far behind risks it hitting the "please upgrade" error the next time it tries to write.
</Tip>

## Summary

| Direction                         | Guarantee                                                                                            |
| --------------------------------- | ---------------------------------------------------------------------------------------------------- |
| Older repository, newer Cloudstic | Always fully readable and writable. No expiry, no migration step required.                           |
| Newer repository, older Cloudstic | Not guaranteed to work. Fails cleanly with an "upgrade Cloudstic" error rather than misreading data. |

This is a deliberate design tradeoff: Cloudstic would rather stop you with a clear error than risk destroying your backups by guessing at a format it doesn't fully understand.

## See also

* [Storage Model](/advanced/storage-model): how objects, packfiles, and indexes are laid out on disk
* [cloudstic check](/commands/check): verify repository integrity
