Changelog
Hier stehen nur veröffentlichte Versionen. Was noch entsteht, steht auf der Roadmap.
Diese Seite listet die Releases, die beim letzten Bau der Website veröffentlicht waren; das neueste Release steht immer auf GitHub ↗.
0.4.7 beta · 29. Oktober 2026
Die Release-Notes dieser Version gibt es nur auf Englisch.
Restow 0.4.7 makes Microsoft 365 backups steadier. Mailboxes of disabled or unlicensed accounts and OneDrives and sites that Microsoft locked are marked "Not backed up" with the reason instead of failing every night, and every object Restow stops backing up waits amber for an admin's confirmation. Backups that Microsoft Graph or the storage held back no longer count as failed, a permission granted to the app takes effect without a new client secret, and one queued backup can no longer block the backup queue of every tenant. Reminders go out before the client secret or certificate of an app registration expires, and many errors of mailbox, OneDrive, SharePoint and IMAP backups and restores now cost an area or an item instead of the whole run. Proxmox VE VMs and containers can be excluded from backup on purpose, and the inventory shows what a guest's first and follow-up backups store as text (#58). The recommended job can switch the mail archive on, and the owner of the installation can enter monthly prices that each tenant's overview turns into an estimate for the provider. Four database migrations (Upgrade Notes).
Breaking changes
status: "orphaned" now also covers objects that are still at the source but are no longer
backed up (account disabled, no licence, or locked by Microsoft): before, it meant removed from
the source. This applies in GET /api/v1/objects, GET /api/v1/users, the object.status of
GET /api/v1/jobs and objects.orphaned of GET /api/v1/status. The new statusReason
(account_disabled, no_license, locked, null for an object removed from the source) of
GET /api/v1/objects, of the object of GET /api/v1/jobs and of the objects of
GET /api/v1/users tells them apart. An integration that treats orphaned as a deleted
account should check statusReason before it acts.
Nothing else changes in a breaking way. The integration API contract moves to 1.7.0, additively.
In GET /api/v1/users the objects also carry inactiveSince and statusConfirmedAt, and a
user's recoveryReadiness reads at least yellow (never green) while one of its objects waits
for a confirmation (yellow instead of null when such an object has no backup to rate). The
readiness summary of GET /api/v1/status and GET /api/v1/verify/latest reports toConfirm;
GET /api/v1/status leaves excluded Proxmox VE guests out of guests.total and
guests.withoutJob and reports them as guests.excluded. POST /api/v1/jobs/backup can skip
an object with the reason inactive, the job.completed and job.failed webhooks of a
completed restore carry data.job.result, and alerts (report.alert) can name the new events
object.inactive, object.inactive_many, source.app_secret_expiring and
installation.app_secret_expiring; clients that handle skip reasons or event names exhaustively
should accept the new values. Some values follow new rules: backups held back by a service and
objects no longer backed up raise no job.failed, objects removed from their source are rated
without the age of their last backup, and objects.failed of GET /api/v1/status leaves out
objects whose latest backup was held back by a service or ended neutral for an object no longer
backed up; the run before it counts instead (Changed, Fixed, Upgrade Notes).
Added
- Microsoft 365: objects that are no longer backed up because the source says they are gone,
disabled, unlicensed or locked first read amber "Not backed up any more, please confirm" with
reason and date (docs/MICROSOFT.md "Nicht mehr gesichert: Bestätigung"). No failure, no red,
not overdue, but they keep the warnings, the dashboard and the tenant's readiness at least at
yellow (never green), are counted in the integration API's
readiness.toConfirm, and providers seeinactive_to_confirmamong a tenant's alerts, until an admin confirms "Yes, intended": per object, or for several in the list by selection or by the list's filter (at most 1000). Through the API (POST /api/v1/directory/objects/:id/inactive/confirm,POST /api/v1/directory/objects/inactive/confirm) a confirmation can carry an optional note (up to 1000 characters) for the audit log; the interface does not ask for one. Tenant administrators and provider teams with configure rights may confirm; each confirmation is audited (directory.inactive.confirmed,directory.inactive.bulk_confirmed). Confirmed objects read grey "Intentionally no longer backed up", with who confirmed it and when. When the object becomes active again, the confirmation is dropped and backups resume; if it stops again later, Restow asks again. An excluded object that disappears from the source was never backed up and counts as confirmed. The list of protected objects filters byto_confirmandconfirmed. Migration 0069 stores the state. - Notification events
object.inactive(a notice, once per object and transition, in the bell by default) andobject.inactive_many(one warning per tenant and day instead of the notices, when more than 10 objects, or more than 20% of the tenant's objects backed up before and at least two, stop being backed up within a day; part of the "Errors and warnings" choice). Both link to the protected objects waiting for a confirmation. Neither has an event of its own in the webhook stream (job.*); a webhook gets them asreport.alertonce they are ticked in the matrix. - Microsoft 365: reminders before the client secret or certificate of the central app
registration expires (docs/ENTRA-SETUP.md, Teil 3, "Ablauf und Erinnerungen"): 30 days
before, again 7 days before and once it has expired, each stage once per expiry date. A new
date or another registration starts over; a date first seen late raises only the stage it is
in, not the earlier ones. The api checks every 15 minutes (the first time two minutes after it
starts; not in the public demo) and raises the new installation event
installation.app_secret_expiring(a warning, an error once expired) for the provider administrators: in the bell, and in the mails and webhooks of every rule that lists it. The date is the one entered under Installation › Microsoft multi-tenant app,ENTRA_CLIENT_SECRET_EXPIRES_ATfor a secret from the environment, or the certificate's own end (notAfter). Restow does not read it from Microsoft Graph, which would needApplication.Read.All. The last reminder is kept insettings.app_secret_alerts(migration 0068) and claimed under a row lock, so neither a restart nor a second api replica repeats it. - Microsoft 365: the same reminders for a source connected through its own app registration
(docs/ENTRA-SETUP.md "Alternative: eine eigene App pro Quelle"), as the new event
source.app_secret_expiringamong the job events, so tenant administrators can choose it as well. The worker checks every Microsoft 365 source of an active tenant that is not disabled (also one in error) every five minutes; a certificate counts by its own end, a client secret by the date noted for it. "Own Graph app" takes the secret's expiry date ("Secret expires on", optional, as Entra shows it under Certificates & secrets), and the source's connection card shows "Expires" with the expiry badge and, within 30 days or once expired, what to do. For a secret the date can be noted, changed or removed there without entering the secret again ("Note expiry date", "Change expiry date";PATCH /api/v1/sources/:id/own-app/expiry, audited assource.own_app.expiry_updated, for tenant administrators and provider roles that may configure). A new secret, a new certificate or a changed date starts the reminders over; saving the same date again does not. - Both expiry events name their stage in the bell ("expires in 5 days", "Renew it now", "has
expired") and lead to the source's page or to Installation › Microsoft multi-tenant app. The
alert mail lists the expiry date, the days left, the kind of credential, the application
(client) ID and how to renew it without a gap (create the new secret, enter it with its new
date, only then delete the old one in Entra); chat webhooks of
source.app_secret_expiringlink to the source's page. Both events are part of the "Errors and warnings" choice and of the bell's default, and each stage passes a rule's throttle on its own. - Restores that did not restore anything: a completed restore with failed items and none
restored reads "Nothing restored" (red) and raises
restore.failedand thejob.failedwebhook, with "Nothing was restored: N items failed." as its error; one that skipped every item reads "Everything skipped" (amber) and staysrestore.completed, saying so instead of claiming it restored something (info, not success, in chat channels). Thejob.completedandjob.failedwebhooks of a completed restore carry its counters indata.job.result(restored,skipped,failures,unverified). - Proxmox VE: an admin can exclude a VM or container from backup on purpose (docs/PVE.md
"Excluding a guest"), for test VMs or guests backed up elsewhere: "Exclude from backup" on
the guest's page, or for a selection of a node's guests in the inventory; "Include again" on
the page and in the guest's inventory row takes it back. Tenant administrators and the
administrators of the provider team may do so. No job backs an excluded guest up, not even
the job for all guests, and the recommended job leaves it out; its own job stays recorded,
so including it again restores what it had. Excluding withdraws its queued backups (one
already handed to the node gets a cancel request, a running one ends as it would); a backup
queued in the same moment is withdrawn at the node's next heartbeat, before the node gets it,
and shows in History as a cancelled run with "The guest was excluded from backup before it
started." "Back up now" and putting the guest into a job are refused (409
urn:restow:problem:pve-guest-excluded) until it is included again; taking it out of its job stays possible. Its restore points stay restorable, retention treats them as before and the weekly restore check of its newest restore point goes on; the job's monthly restore test and boot tests no longer cover it. New routePUT /api/v1/pve/guests/:id/excluded({ "excluded": true }orfalse), audited aspve.guest.excludedwith the number of queued backups withdrawn before reaching the node (one already handed to the node is not counted); excluding a guest twice changes nothing.GET /api/v1/pvereportsexcludedAtandexcludedByper guest (migration 0066). - Proxmox VE: excluded guests count nowhere as unprotected: not in the overviews, the recovery
readiness, the warnings,
backup.overdue, the statistics, the job counts of the all-tenants view or the provider view, and they never keep a tenant from green. The guest counts report them asexcluded; their restore points stay in the count of restore points and their earlier runs in the history. In VMs & containers an excluded guest reads "Excluded" (grey, never a problem, whatever its earlier runs said), matches only the new state filter "Excluded" and sorts after every problem. The inventory shows "Excluded: N" per node, the guest's detail panel says "Excluded from backup" under its job, which cannot be changed there, and the job dialog no longer offers excluded guests. - Recommended job with the mail archive (docs/ARCHIVE.md "Archiv im Mail-Job"): while the
installation offers capture from the mailbox (
archive.mailboxCapture) and the tenant has mailboxes or accounts an archive can capture, "Create recommended job" and "Protect everything without a job" make the new mail job over all objects back up and archive. A mail job over all objects that exists and does not archive yet is switched to archiving instead ("Switch archiving on in …"); its schedules stay, and the change is audited asbackup_job.updatedwithchanges.archive, like an edit in the job editor. The click uses the default capture ways, which need nothing set up in the tenant: Microsoft Graph for Microsoft 365 mailboxes, IMAP sync for the other accounts. Journaling and forwarding stay a choice in the editor. Without the capture the recommended job is made as before. - The recommended job never changes a mail job over selected objects; its preview names them ("Archiving stays as it is in …"). A mail job over all objects whose capture ways were chosen by hand (Microsoft Graph or the IMAP sync switched off, for example journaling only) is left as it is, and the preview says so. A new job over all objects is made only when it covers something that is in no job yet. The dialog says when the job over all objects archives already, the confirmation names the jobs in which archiving was switched on apart from the jobs set up, and the preview of a paused job names no schedule.
- The list of mail jobs shows "Switch archiving on" while the installation offers the capture and the recommendation would switch an archive on in the mail job over all objects (not for tenants with only OneDrives, SharePoint sites or groups, nor for jobs whose capture ways were chosen by hand).
- Installation › Prices: a monthly price per mailbox and per GB or TB of stored backups, in
EUR, CHF, USD or GBP (docs/ARCHITECTURE.md "Mandantenmodell"). Mailboxes are counted as in
the mailbox usage (a OneDrive does not count twice); storage is the tenant's stored backups,
deduplicated and compressed, in decimal units (1 GB = 10^9 bytes, 1 TB = 10^12 bytes). Prices
take at most four decimals; a price left empty is not shown. Provider admins with every
tenant read them, only the owner changes them, audited as
settings.pricing.updatedwith the values before and after (GETandPUT /api/v1/settings/pricing). Tenant users never see them. - Each tenant's overview shows provider admins with every tenant a card "Price per month": what the tenant comes to at these prices, one line for the mailboxes and one for the storage, with a link to the prices. It appears once a price is set. Restow bills nothing and limits nothing.
Changed
- Backups that Microsoft Graph or the storage held back no longer count as failed. A Mail &
SaaS backup that ends, after all its retries, with
graph.throttled,graph.service_unavailableorstorage.rate_limitedreads "Held back by the service, retried" in amber instead of "Failed" in red (in the objects list "Held back by the service") in every view: History, the all-tenants job overview, the objects list, the runs of a job, the job page, the recent jobs on the dashboard and the run details. It is left out of the failed counts of the statistics and the dashboard, does not make the job failing (the run before it stands), does not make a warning red or end its acknowledgement, and raises nobackup.failedalert and nojob.failedwebhook. The next scheduled run tries again; an object held back for longer is caught by the overdue and readiness rules, which look at the age of the newest backup. A restore, export, import or check that a service held back has no next run and stays a failure, withrestore.failedand the like. - Microsoft Graph: a background job honours a Retry-After of up to 5 minutes (before, waits were capped at about a minute, and Exchange refuses a retry before its mailbox concurrency penalty is over); a cancelled or expired job still stops at once. Requests from the interface keep the one-minute cap.
- Overdue backups (
backup.overdue): a mailbox member with a schedule of its own is judged by that schedule or by the tenant's mail jobs (the most relaxed one), whichever allows longer, for that member only; a weekly member of a daily job is no longer overdue two days after its backup. An object whose backup has started and is still running (up to 21 days, a large first backup) is not overdue; a backup that only waits in the queue does not hold the alert back. - The expiry badge of the central app (Installation › Microsoft multi-tenant app) turns amber
30 days before the end instead of 60 and red from 7 days, counted in whole calendar days
(UTC); a source's own app shows the same badge. For a secret from the environment without
ENTRA_CLIENT_SECRET_EXPIRES_ATthe page says how to set it. The setup texts and docs/MICROSOFT.md say 30 days, 7 days and expired instead of 60 days. - The job page names the phases of a SharePoint site backup ("Reading the site", "Lists") and of the discovery of sites and group mailboxes. The retention notes read "the newest restore point of each object is always kept" in the singular.
- Proxmox VE inventory (#58): the size of a guest's first backup ("First backup on : stored") and what a follow-up backup adds on average ("Average per follow-up backup: + (last N backups)") are shown as text in the guest's row, not only in its tooltip, so they can be read and copied.
- Dependencies: better-auth 1.7.14, mailparser 3.14.1, nodemailer 10.3.1, smtp-server 3.21.3, msgreader 1.29.0, Biome 2.6.4, Vitest 5.0.5, Vite 8.3.5, React 19.3.1 and, in the release pipelines, docker/login-action 4.7.0 (Dependabot #82 to #85). pg-boss 10.4.2 carries a patch of Restow's (Fixed, Upgrade Notes). zod 4 (Dependabot #86) is not part of this release.
Fixed
- Microsoft 365: a mailbox whose account is disabled or has no Exchange Online licence
(mailbox not provisioned, licence removed, inactive mailbox) no longer fails its backup until
the next directory sync ("Microsoft rejected the request"). The backup confirms with
Microsoft that the user exists but has no mailbox, marks the mailbox "Not backed up: account
disabled" or "Not backed up: no licence" and ends neutral (
graph.mailbox_inactive): no failed count, no red readiness because of age, not overdue, nobackup.failedalert orjob.failedwebhook, existing backups kept. The directory sync sets the same state from its mailbox probe. Only Exchange's answer counts: a disabled account whose mailbox Microsoft still serves (a shared mailbox, a former employee) is backed up as before. A 401 or 403 is never read this way; those stay permission failures. Backups resume right after the directory sync that finds the account enabled or licensed again, and the mailbox is not reported overdue because of its old backup. A restore into the original mailbox is refused with the reason (docs/MICROSOFT.md "Deaktivierte und unlizenzierte Konten"). - Microsoft 365: a OneDrive or SharePoint site that Microsoft locked (HTTP 423
resourceLocked, "Access to this site has been blocked"; Microsoft does this to the OneDrive of an unlicensed account) no longer fails every night as "Microsoft rejected the request". The backup confirms the lock with one cheap read, marks the object "Not backed up: locked" (graph.object_locked, neutral, no retries) and the scheduler stops planning it. The directory sync's drive probe recognises the same lock and marks a known OneDrive "Not backed up: locked" at once, before a backup meets it. A 423 that this read does not confirm stays a counted failure with itsbackup.failedalert. A site whose libraries all answer 423 ends without a restore point instead of carrying old copies forward. The directory sync never turns a locked object active again just because it is still listed: it reads each locked drive or site once more and resumes the backup only when that read succeeds; otherwise it keeps the lock and reports that the check failed. A 423 on a single file stays an item problem (docs/MICROSOFT.md "OneDrive: Sichern und Wiederherstellen"). - Job queue: one queued backup of an object whose backup was still running (the next scheduled run, "Back up now") blocked the backup queue of every tenant until that backup ended, because pg-boss kept offering it first and handed out nothing. Such a job now waits for its object's running backup and lets every other backup pass (pg-boss 10.4.2 with patches/pg-boss@10.4.2.patch).
- Microsoft 365: a permission an administrator grants to the app after Restow fetched its
token now takes effect without a new client secret. A token carries the app's permissions as
they were when it was issued, and Restow kept it until shortly before it expired (up to about
an hour), so a permission granted in between was refused until then or until a new secret
was entered. When Graph answers 401 or 403, Restow now fetches a new token once and sends the
request again, at most once a minute per tenant or source, so a run of refusals (an item the
app may not read) does not fetch a token each time. Every request refused with the same old
token is sent again with the new one, not only the first, and refused sub-requests of a
$batchare sent again once as well; a wall clock that stepped back (NTP, VM resume) no longer holds back the refresh. A request refused again with the new token fails as before. This applies to backups, restores, the directory sync, the archive capture, the group search, the connection test and the consent check. A token endpoint that cannot be reached is asked twice more (after 1 and 4 seconds, 60 seconds per request) and then fails the run, which resumes from its checkpoint, instead of recording every item as failed; the test of an app registration still reports it at once. - Microsoft 365: every
$batchnow sends an identical read only once and gives the answer to every caller, also in the retries after 429 and a new token, on top of the unique request ids of 0.3.2, so a delta page or a retry that names the same message twice can never repeat an id ("Request Id ... has to be unique in a batch"). Writes are never merged. - Microsoft Graph: a connection broken before Graph answered (reset, refused, a temporary DNS
failure, a timeout) is retried with backoff for requests that only read,
$batchof reads included, and is not reported as throttling. - Mailbox backup: a 403 for calendars or contacts (permission missing, an access policy that covers mail only) fails that area and keeps the mail of the run, instead of discarding the snapshot. A 401 in the middle of a run checkpoints and resumes, instead of abandoning a partial first backup. A well-known folder Graph refuses to resolve (400, 403) is treated as absent and logged, instead of failing the mailbox before a single folder was read. A stored delta link Graph rejects as an invalid sync state (400) leads to a full resync, instead of failing on every run. A message Exchange cannot convert to MIME (conversion error, or a plain 500 after one more try) is stored as JSON with its attachments, like an oversized one. A subfolder deleted while its parent was listed no longer fails the run; it is recorded as a failure of the parent, and what the snapshot holds below the parent stays until the parent is gone.
- SharePoint: a library or list Graph will not give (400, 501, or a lasting 500 for a list template or a library's permissions) is reported as an item failure and keeps its last copy; the rest of the site gets its snapshot, instead of the whole site failing; a 500 or 502 for a library's contents still fails the job, which resumes from its checkpoint. A resumed site counts the item failures of the libraries an earlier attempt finished. A library that is gone no longer reads "this user has no OneDrive".
- OneDrive and SharePoint: an item that failed and came through later in the same run (listed
twice in a delta feed, retried) no longer stays among the failures. Files a host sends
compressed are no longer taken for truncated downloads. A OneDrive whose drive Graph no
longer finds (user deleted, retention over) fails as "OneDrive unavailable"
(
graph.onedrive_unavailable), permanent and not retried, instead of as an item. Cancelling a job during a throttling wait no longer records items as failed. - Recovery readiness: an object removed from its source (a mailbox deleted in Microsoft 365,
for example) no longer turns red because its last backup grows old. Nothing backs it up any
more, and retention always keeps its newest restore point, so it is rated by whether that
backup restores, without the age reasons ("The latest backup is N days old"), and is never
overdue. A kept backup that does not restore stays red. The same rating applies in the
statistics, the objects list, the tenant's overall readiness, the integration API
(
GET /api/v1/status,/objects,/users,/verify/latest, wherereport.reasonsleaves the age out), theverify.completednotification and the rating a new check stores. The table says "Removed from source, backups kept" instead of "Removed from source"; the report page opens with a note "Removed from the source" and lists the age of the kept backup as "Not counted: ..." instead of among the findings. An object whose newest backup was never checked gets one more check from the weekly verify planner and from a job's verify; after that nothing is planned for it. - IMAP backup: a login the server refuses for now (too many connections for the account, an
authentication backend that is down, [UNAVAILABLE], [INUSE] or [LIMIT]) is the new transient
cause
imap.server_limit, retried by itself, instead of a wrong password; the connection test of an IMAP source says "The server temporarily refused the login". [LIMIT], [OVERQUOTA] or a quota text on a read is no longer reported as a full mailbox but asimap.server_limittoo: such a download cap fails the folder as a whole and the next run resumes, instead of one failure per message (a cap the server reports on a read without such a code or text still costs one failure per message). Messages deleted or moved during the backup are not counted as failures. A run whose connection dropped too often fails asimap.connection_lost(transient) instead of "cause not identified". - IMAP archive capture: a message the server refuses or does not deliver no longer holds back its folder or the whole pass; the other messages are captured, and after three passes the capture gives up on it. A refused folder costs only that folder for this pass. Folders a pass did not reach keep their state, so older mail is no longer skipped after an interrupted pass. A limit of the account stops the pass with its state kept. A watch refused with a NO on EXAMINE or IDLE is retried after minutes (doubling up to an hour), instead of being taken for a server without IDLE for a day.
- Restore: an IMAP restore whose connection drops fails and is retried on a fresh connection, where the Message-ID check skips what was already appended, instead of ending "completed" with every remaining item failed. A retried SharePoint list restore in "keep both" mode no longer adds the items the interrupted attempt added, and a retried contacts restore in that mode no longer creates contacts twice. A restore into a mailbox given by address resolves the same mailbox the API accepted (through the directory user's address, never an orphaned or imported mailbox), so a duplicate address no longer picks another one.
- Jobs: the time limit of a job counts from when the queue handed it out, also while it waits
for a free slot of its tenant; a job that waited out its time stops before it starts, so no
retry runs beside a late attempt. A cancel that lands while the attempt starts or fails is
kept (it was overwritten by "active" or "failed" and retried). A job the reconciler ends for
good raises the
job.failedwebhook, the bell and the notification rules like any other, and its checkpoint is cleared. - Public demo: the seed no longer fails when Restow queued an object's first backup itself
after the seed had listed the objects. "Back up now" then answered
already_queued, the seed counted the object as failed, the nightly reset leftwebdown and the demo kept showing its "being reset" page. The seed now waits for the backup that is already queued. - "Remove from Restow" no longer says file restore stops offering the backups of a removed machine: since 0.4.6 its page offers their restore until they are deleted.
- The licence page no longer lists sign-in with Microsoft among what Business unlocks; it is still experimental and off by default.
Security
- ip-address 10.7.5 (from 10.7.2), a transitive dependency through socks, resolves a moderate advisory reported by Dependabot. socks comes with the IMAP library imapflow and is used only for connections through a SOCKS proxy, which Restow does not configure.
- seroval 1.7.5 (from 1.6.7, through the TanStack router) resolves GHSA-7rv5-mrxv-xcr9, GHSA-wp97-x4hv-qvhp and further advisories of its deserializer; zod 4.6.7 (from 4.6.5, an override for the copy better-auth uses) resolves GHSA-mrhx-c7xc-m3w5 there.
- GHSA-mrhx-c7xc-m3w5 (memory use when validating a large array) also names zod 3, which
Restow's own request validation uses and for which no fixed 3.x exists. The audit of CI
ignores this one advisory (
pnpm.auditConfigin package.json) until 0.4.8 moves Restow to zod 4. The request body limit of the api (1 MB on most routes,apps/api/src/middleware/body-limit.ts) bounds it: a 1 MB array that fails element by element costs about 150 MB and a second of the api for that request.
Upgrade notes
New images and four database migrations; no new required environment variable, and the
docker-compose.yml of 0.4.0 stays.
- Four database migrations run at the api's start; none of them rewrites a table:
- 0066 adds two nullable columns to
pve_guests(excluded_at,excluded_by). - 0067 adds the column
settings.pricing(jsonb, default{}, no price set). - 0068 adds the column
settings.app_secret_alerts(jsonb, default{}). - 0069 adds five nullable columns to
protected_objects(status_reason,inactive_since,inactive_notified_at,status_confirmed_at,status_confirmed_by), two check constraints and a trigger that keeps them in step with the object's status; it updates only the orphaned rows.
- 0066 adds two nullable columns to
- New optional environment variable
ENTRA_CLIENT_SECRET_EXPIRES_AT(YYYY-MM-DD, as Entra shows it): a central app whose secret comes from the environment gets expiry reminders only with it in.envand the api restarted. A certificate needs none; an unreadable value counts as unknown. - Sources connected through their own app before 0.4.7 have no expiry date, so no reminder: for a client secret, note the date on the source's page under "Expires"; a certificate gets its date when it is entered again.
- Webhooks and notification recipients get the new events (
object.inactive,object.inactive_many,source.app_secret_expiring,installation.app_secret_expiring) only once they are ticked in the notification matrix (docs/ARCHITECTURE.md "Benachrichtigungsmatrix: welcher Kanal welches Ereignis bekommt"); a bell column that was never changed shows them. - Objects already orphaned before the update count as confirmed (
migration) and raise no notice, so no long amber list appears. Disabled and unlicensed mailboxes, and OneDrives and sites that Microsoft locked, that failed every night are recognised by the first directory sync or backup after the update (a locked site by its first backup): expect oneobject.inactivenotice for each object (an unlicensed user often has two, mailbox and OneDrive), or oneobject.inactive_manywarning for a tenant with many, and confirm them under protected objects once they are intended. - Webhooks and alerts: a backup that Graph or the storage held back (
graph.throttled,graph.service_unavailable,storage.rate_limited) and a backup that ends neutral for an object no longer backed up (graph.mailbox_inactive,graph.object_locked,config.object_inactive) raise nobackup.failedalert and nojob.failedwebhook; the overdue rules speak up when no backup gets through. A restore that completed without restoring anything while items failed now raisesrestore.failedandjob.failed, withdata.job.statusstillcompleted. A job the reconciler ends for good raisesjob.failed. - Integrations:
GET /api/v1/jobskeeps the statusfailedfor these held-back and neutral backups; readfailure.code(and the object'sstatusReason) and treat them like the object's state, not as a failure. - The counting reads the cause stored with each run, so earlier runs that ended with
graph.throttled,graph.service_unavailableorstorage.rate_limitedalso read "Held back by the service, retried" after the update and leave the failed counts of past periods in the statistics and the dashboard. Objects removed from their source are rated without the age of their last backup from the update on, without a new check; those whose newest backup was never checked are checked once by the next planned check. - Proxmox VE: no guest is excluded by the update; guests in no job keep counting as "in no backup job" until an admin excludes them. restow-pve needs no update in this release (no change to the agents or the Proxmox VE plugin); the server withdraws the backups of an excluded guest before a node gets them.
- Prices are empty after the update; the price card appears only once the owner enters a price
under Installation › Prices. Existing mail jobs change only when an administrator applies
the recommended job, and only where the installation offers
archive.mailboxCapture. - Building from source: pg-boss 10.4.2 is patched through
pnpm.patchedDependencies(patches/pg-boss@10.4.2.patch), whichpnpm installapplies; keep thepatchesfolder. The images carry the patch. - Rollback to 0.4.6 after the migrations was not tested: take a database backup before the update and restore it to go back.
Known issues
- The detection of disabled, unlicensed and locked objects was tested against a simulated Graph API. An answer of Microsoft that Restow does not recognise as "no mailbox" or as a lock stays a counted failure, as before.
GET /api/v1/jobshas no field that sets a held-back or neutral backup apart from a failed one; integrations that open tickets from it can readfailure.code.- Notification mail sent through a Microsoft 365 app registration does not fetch a new token
after a refusal: a
Mail.Sendpermission granted later takes effect once the cached token expires. - The expiry date of a client secret is not read from Microsoft: without a date entered (under
Installation, in
ENTRA_CLIENT_SECRET_EXPIRES_ATor on the source) there is no reminder. Sources with an older own secret without an own app (shared client ID) have no date in Restow; switch them to an own app or the central app (docs/ENTRA-SETUP.md "Alternative: eine eigene App pro Quelle"). - On the Recovery readiness reports list, a filter on the rating matches the stored rating. A report stored before the update, or while the object was still at its source, counts the backup's age, so such a report of an object removed from its source can be listed under red while it reads green. Checks from 0.4.7 on store the rating without the age. The readiness history of earlier days does not show the yellow of unconfirmed objects: only the current confirmation is stored, not when it was given.
- A message the IMAP archive capture gives up on (after three passes), messages the backfill could not read and a well-known mail folder Graph refused to resolve are named in the worker log only, not in the interface.
- Excluding a selection of Proxmox VE guests in the inventory sends one request per guest (there is no bulk route); when one fails, the guests before it stay excluded and the list refreshes.
- Group calendars and conversations were tested against a simulated Graph API, never against a real Microsoft 365 tenant (as in 0.4.5).
- IMAP sources with OAuth2 still cannot be created in the API or the interface.
- The known issues of 0.4.4 still apply.
Verification
Before the tag, on the release branch (0.4.6 plus the 0.4.7 work): lint and typecheck of all
workspaces, the unit and Postgres suites of every package on Postgres 16 (with the Postgres
guard), among them migrations 0066 to 0069 with the trigger and backfill of 0069, the directory
sync and backup tests of disabled, unlicensed and locked objects, the $batch and token tests,
the job queue with the pg-boss patch, the guest exclusion, the prices and the recommended job
with the archive; restic-backed tests with restic 0.19, the web DOM tests, the v1 OpenAPI test,
the tests of the CI scripts and the third-party notices. The handling of locked OneDrives and
sites and of disabled and unlicensed accounts was not run against a real Microsoft 365 tenant
before the tag, beyond the production error data that led to it; the guest exclusion was not
run against a real Proxmox VE node.
Release pipeline, 2026-10-29:
| Check | Result | Duration |
|---|---|---|
| 1. Install: images, compose up, migrations (new install and upgrade) | PASS | 92s |
| 2. Health endpoints, worker and scheduler registered | PASS | 0s |
| 3. Passkey sign-in E2E with a virtual authenticator, tenant creation, i18n de/en | PASS | 2m 10s |
| 4. Microsoft 365 backup and restore against the dev tenant | SKIPPED | 0s |
| 5. IMAP backup and restore against Dovecot, hash comparison | PASS | 8s |
| 6. Journal receipt, chain verification, export | PASS | 3s |
| 7. Standalone restore with restow-restore from the storage of check 5 | PASS | 25s |
| 8. Storage targets: S3 (Garage), local path, mounted directory | PASS | 20s |
| 9. Image scan (Trivy) and dependency audit (pnpm audit) | PASS | 19s |
| 10. Endpoint backup: the agent enrolls, backs up a folder, restores it | PASS | 11s |
| 11. Mail import (folder and upload) and export (EML ZIP, MBOX), compared by hash | PASS | 8s |
| 12. File share backup against Samba: back up, browse, ZIP, restore with permissions, copy job | PASS | 2m 17s |
| 13. Archive capture: IMAP sync with IDLE and backfill, forwarded copies, dedupe, chain | PASS | 2m 09s |
12 of 13 checks passed in full, 0 partly, 1 skipped, 0 failed. The full report, including the reason for every skipped or partial check, is attached to the release as smoke-report.md.
The Community images were smoke-tested on their own (smoke-report-community.md, smoke-report-community-arm64.md): amd64 PASS with gaps: 9 of 13 checks passed in full, 0 partly, 4 skipped (see the reasons below); arm64 PASS with gaps: 9 of 13 checks passed in full, 0 partly, 4 skipped (see the reasons below).
Release-Notes von 0.4.7 auf GitHub ↗
0.4.6 beta · 23. Oktober 2026
Die Release-Notes dieser Version gibt es nur auf Englisch.
Restow 0.4.6 fixes restoring Proxmox VE containers, which failed on current Proxmox VE for every restore and every boot test of a container, and stops a new backup chain from being flagged as a ransomware attack. Removed machines keep their backups browsable until they are deleted, a requested restore check says it is queued until its result is in, and error texts open in a card that can be copied. No database migration.
Breaking changes
None. The integration API contract stays at 1.6.0.
Added
- Removed machines (#65): until their backups are deleted, the page of a removed machine offers their restore (and nothing else), and the restore points, browsing, the ZIP download and the repository key keep working for them, audited as before. The list of removed machines links "Restore files". Restoring onto the machine and every other action stay refused (404); once the backups are deleted the machine is gone for every reader (docs/AGENT.md).
Changed
- Error texts behind a badge or a cut-off line (the boot test, the restore check of a VM or container on its page and in the recovery readiness table) open on hover or keyboard focus in a card with the whole text, selectable and with a Copy button, instead of a browser tooltip.
- A boot test that did not boot shows the node's message under its badge, on the guest's page and in the recovery readiness table.
- "Check now" of a VM or container: the row says "Check queued" under the last check, and the guest's page above the earlier result, until the result is in; both refresh every few seconds meanwhile.
- Dependencies: happy-dom 21.0.4 (tests of the web interface only; Dependabot #78).
Fixed
- Proxmox VE: restoring a container from Restow failed with
Can't use string ("restow") as a HASH refon current Proxmox VE, which passes the storage ID to the backup provider's container restore before the info hash. Boot tests of containers ("Did not boot") and "Restore as a new guest" of containers were affected; VMs were not. The plugin of restow-pve accepts both forms; it is installed with the restow-pve update, which reloads the PVE daemons. - Ransomware detection: the first backup of a container's new backup chain (its repository was missing, or reset) was judged against the old chain and flagged as suspicious, since every file is new in an empty repository. The baseline now begins with the newest chain. A restore point flagged that way before the update stays flagged; mark it as a false alarm.
- The first backup of a container's new backup chain is called "First backup", not "Incremental".
Upgrade notes
- No database migration and no new setting.
- Update restow-pve on every Proxmox VE node (the server offers it after its own update; nodes update themselves when idle) before relying on container restores or boot tests. Until then, container restores keep failing as before; VMs are not affected.
- Container restore points that read "Did not boot" or a failed restore check from before 0.4.3: run "Boot test now" or "Check now" once the node is updated.
Known issues
- The known issues of 0.4.5 still apply.
Verification
Before the tag, on the release branch (0.4.5 plus the 0.4.6 fixes): lint and typecheck of all workspaces, the unit and Postgres suites of every package on Postgres 16 (with the Postgres guard), restic-backed tests with restic 0.19, the web DOM tests, the Perl tests of the Proxmox VE plugin (the container restore with and without the storage ID) and the third-party notices. The release smoke runs in the release pipeline; the container restore fix was not run against a real Proxmox VE node before the tag.
Release pipeline, 2026-10-23:
| Check | Result | Duration |
|---|---|---|
| 1. Install: images, compose up, migrations (new install and upgrade) | PASS | 81s |
| 2. Health endpoints, worker and scheduler registered | PASS | 0s |
| 3. Passkey sign-in E2E with a virtual authenticator, tenant creation, i18n de/en | PASS | 2m 06s |
| 4. Microsoft 365 backup and restore against the dev tenant | SKIPPED | 0s |
| 5. IMAP backup and restore against Dovecot, hash comparison | PASS | 8s |
| 6. Journal receipt, chain verification, export | PASS | 3s |
| 7. Standalone restore with restow-restore from the storage of check 5 | PASS | 24s |
| 8. Storage targets: S3 (Garage), local path, mounted directory | PASS | 21s |
| 9. Image scan (Trivy) and dependency audit (pnpm audit) | PASS | 18s |
| 10. Endpoint backup: the agent enrolls, backs up a folder, restores it | PASS | 11s |
| 11. Mail import (folder and upload) and export (EML ZIP, MBOX), compared by hash | PASS | 10s |
| 12. File share backup against Samba: back up, browse, ZIP, restore with permissions, copy job | PASS | 2m 14s |
| 13. Archive capture: IMAP sync with IDLE and backfill, forwarded copies, dedupe, chain | PASS | 2m 12s |
12 of 13 checks passed in full, 0 partly, 1 skipped, 0 failed. The full report, including the reason for every skipped or partial check, is attached to the release as smoke-report.md.
The Community images were smoke-tested on their own (smoke-report-community.md, smoke-report-community-arm64.md): amd64 PASS with gaps: 9 of 13 checks passed in full, 0 partly, 4 skipped (see the reasons below); arm64 PASS with gaps: 9 of 13 checks passed in full, 0 partly, 4 skipped (see the reasons below).
Release-Notes von 0.4.6 auf GitHub ↗
0.4.5 beta · 23. Oktober 2026
Die Release-Notes dieser Version gibt es nur auf Englisch.
Restow 0.4.5 prepares the licence for paid update periods: keys can carry an update period and a series, the image knows its release date, and an installation is offered, told about and allowed to install only the releases its Business or Service Provider key covers. Every key issued so far is a beta licence and keeps covering every 0.x and 1.x release. Revoked machines can be removed from Restow, with or without their backups; Microsoft 365 group calendars and conversations are backed up as protected objects of their own (opt-in); both job lists can start and stop every job and open a detail panel like VMs & containers. The public demo resets from a saved template in about a minute. Three database migrations (Upgrade Notes).
Breaking changes
None. The integration API contract moves to 1.6.0, additively: ObjectKind includes
group and the status reports lastSuccess.groups; clients that handle object kinds
exhaustively should accept the new value. Licence keys with the new optional members verify
only on 0.4.5 and later (ee/licensing/KEY-FORMAT.md).
Added
- Licence keys carry update terms (docs/LICENSING.md). The key format
restow-license-v1accepts the optional membersseries,updates_untilandkidand ignores members it does not know, so keys the licence server issues later keep verifying; the six members of today stay required and keep their rules (mailbox_limitunchanged). Every key issued so far is a beta licence: it covers every 0.x and 1.x release. A key withupdates_untilcovers every release made up to the end of that day (UTC).kidnames the vendor signing key, for a rotation without breaking issued keys. The contract for the issuer, with examples, is ee/licensing/KEY-FORMAT.md. - The image carries its release date (
RESTOW_RELEASED_AT, from the build argumentRESTOW_CREATED, the commit date of the release tag);GET /api/v1/statusreports it asreleasedAt. Release notes publish the same date in areleased:line next to the digests. - The update check marks releases the installed Business or Service Provider key does not
cover, says so calmly on the Updates page (the installed version keeps working; the newest
covered version installs as usual) and refuses to install or plan them (409
urn:restow:problem:update-not-covered). The bell and theupdate.availablealert rules announce only the newest covered release. - Started by hand, a release the installed Business or Service Provider key does not cover
stops before its database migrations, with a log line naming the version, the end of the
update period and the last covered release date; nothing needs to be restored to go back.
With
RESTOW_RUN_AS_COMMUNITY=1it starts as Community instead (the modules stay off, no data is changed). Never for beta licences, development builds, installations without a key or the demo. - The licence page shows which updates the key includes ("all 1.x (beta license)" or the end
of the update period) and, from 30 days before the end, a short notice on the same page.
A new key of the same edition replaces the active one even while it is in force (a
renewal); earlier keys stay in the history, and every installation or replacement is
audited with the key's update terms and whether they cover the running version. A key that
does not cover the running version is refused (
outside_update_period). - Public demo, fast nightly reset (deploy/demo/README.md "Fast reset"): after a full seed
deploy/demo/reset.shsaves a template (apg_dumpof the demo database, its roles and a tar of every volume the seed writes) keyed by the release, the image ids and.env, and restores it the following nights instead of seeding: the database is restored next to the running one and swapped in, so the demo is offline for about 15 to 25 seconds instead of many minutes. The restore moves every system time forward by the template's age (deploy/demo/seed/sql/ shift-time.sql), so the history still ends today and "last backup 12 minutes ago" stays true; the audit log, the mail archive and restic's own snapshot times keep their real times, sign-ins are removed. A template older thanRESTOW_DEMO_TEMPLATE_MAX_AGE_DAYS(default 7), a new release, new images, a changed.envor a failed restore lead to a full seed. Two templates are kept, with a free-space check before saving (RESTOW_DEMO_TEMPLATE_*settings,RESTOW_DEMO_TEMPLATES=falseswitches it off). - Machines: a revoked machine can be removed from Restow (#65). "Remove from Restow" in its
danger zone offers "Remove from the list, keep the backups until they expire" (the newest
backup plus the longest rule of the machine's retention, read as time) or "Delete the machine
and its backups", with the hostname typed and a recent sign-in. The machine leaves every list,
picker, dashboard and count and its backup job; its runs, reports and audit entries stay. The
worker deletes its restic repository (
endpoints/<id>/) on every target that holds files of it: the primary, its copies and retired primaries. Deleting now is refused while a legal hold over the tenant or an unresolved suspicious restore point holds the backups, and the worker waits for such a hold when the backups expire. Objects the storage still locks (S3 Object Lock, a directory's deletion delay) are deferred until their lock runs out, recorded like a refused prune and left out of the lock renewal. The machines page lists the removals still pending, with the date, the hold or the lock. Every step is audited. Database migration 0064 adds the removal state toendpoints. - Machines: an uninstall that waits for a machine that is off now offers "Revoke now", and a machine without contact for longer than a configurable number of days (default 30, under Alerts of the machine) suggests revoking it, on its page and among what needs attention (#65). The machine's detail panel on Inventory shows the suggestion as a state and offers "Revoke now" and, once the machine is revoked, "Remove from Restow" as well.
- Repositories: a warning when a directory repository lies on the system disk of the Restow server, the disk under the operating system, Docker and the database (a full system disk stops everything, as on 16 October 2026). The api recognises it from inside its container by device and block device of the path, the installation default and the mounter's shares included; it is shown on the Repositories page, in the "Backups land in" line of the job editors and on the dashboard's storage tile, where provider admins also see the free space, its trend over the last week and when the disk would be full. The api now also watches the system disk for low disk space. Nothing is blocked.
- Microsoft 365 group mailboxes as protected objects of their own kind
group(docs/MICROSOFT.md "Gruppenpostfächer"): the calendar and the conversations of Microsoft 365 groups and of the groups behind Teams. The directory sync readsgroups/deltaas a second delta stream next to the users (a full enumeration on the first and every full sync, only changes in between, its delta link stored with the rows), keeps only Microsoft 365 groups and orphans removed ones. Group mailboxes are opt-in: the protection rules get a switch "Protect all Microsoft 365 groups" (groups:selectedby default, orall), and single groups can be included in the list of protected objects. A mail job with scope "all" covers every protected group, like sites. Group mailboxes never count as protected mailboxes. - Group mailbox backup: the group calendar through the same calendar code as a user's (series
masters with their exceptions), falling back to the group's
calendarViewand one read per series master when Graph refuses the event listing to the app; a calendar Graph refuses entirely is a warning on the run, not a failure. Every post of every conversation is stored as an RFC 5322 message undermail/Conversations(with its file attachments when Graph hands them out, otherwise their absence is recorded); only threads with new posts are read again. A group that no longer exists fails with the new causegraph.group_unavailable. Migration0065_group_mailboxes(an enum value only). - Group mailbox restore: the restore explorer lists groups in the "SharePoint & Teams" section
with the areas "Group calendar" and "Conversations"; download (EML, JSON) and export (EML,
MBOX, PST) work as for mailboxes. A restore into a user's mailbox brings back events and
conversations; a restore into the group brings back calendar events only, because Microsoft
Graph lets no app post into a group conversation (each post is reported as not restorable,
with the ways that work). Restoring a group is no impersonation. The integration API reports
lastSuccess.groupsandObjectKindincludesgroup(integration API contract 1.6.0, additive; clients that handle object kinds exhaustively should accept the new value), and the dashboard lists group calendars and conversations among the last backups. No new Microsoft permission is needed:Group.Read.AllandCalendars.ReadWritewere always required. - Start now and Stop on every row of both job lists (Servers & clients and Mail & SaaS) and in
the row's "…" menu: one button of a fixed size that says "Start now", "Stop" while the
job's backups run or wait, and "Stopping…" once asked. Stopping asks first and says what it
means for the kind of job. New API routes:
POST /api/v1/backup-jobs/:id/cancel(every queued or running backup of a mail, machine, share or copy job in one set-based request; audited asbackup_job.run_cancelledon the job and per machine),POST /api/v1/pve/jobs/:id/run(a backup of every guest a Proxmox VE job covers, like its schedule would, without moving the schedule;pve.job.run_requested) andPOST /api/v1/pve/jobs/:id/cancel(pve.job.cancelled). For tenant administrators and provider roles that may operate, closed in the public demo. - Detail panels on Inventory and on the job lists, like the one of VMs & containers: a click on
a row, its name or its state opens it (
?machine=<id>on Inventory,?job=<id>on the job lists, so a link opens it). It lists every state, the full error and warning texts of the newest backup or failed run in a copyable monospace block (for a machine also the end of the log), what needs attention, the restore checks, the key facts, the newest runs and the actions.
Changed
- Dependencies: major update of the translation libraries, i18next 26 and react-i18next 17 (updated together). Texts, plurals and number and date formats read exactly as before in English and German.
@azure/msal-nodeis no longer a dependency: nothing used it. The Microsoft 365 app tokens, the admin consent and the IMAP OAuth2 sign-in use Restow's own token client, unchanged.- Public demo: the health checks of postgres, Dovecot and the api run every 2 to 5 seconds instead of every 10 to 15 (with the same grace period), and the full reset stops the old project with a 10 second timeout, so a reset waits less for services that are already ready or about to be discarded.
- Inventory and the job lists keep their layout like VMs & containers: fixed column widths, one row height (loading rows included), one compact state badge per row (the most urgent of what applies; green only for a passed restore check), the progress of a running backup beside it, one-line cells without tooltips, and action buttons of one size. Columns that do not fit a screen give way from the right; the panel has everything.
- "Run now" of a job is called "Start now".
Fixed
- Public demo:
reset.shnow readsRESTOW_DEMO_COMPOSE_FILESfromdeploy/demo/.envas the README always said, not only from its environment, and logs which compose files a run uses. A list from.envthat would publishwebon every interface (the own-VM override with 80/443) is used only together with the newRESTOW_DEMO_PUBLISH_PUBLIC=true, so a co-hosted host whose.envcarries that line keeps running as before; entries that are not compose files indeploy/demo/are refused before anything is stopped. - Restore explorer: a mail message stored as JSON (too large for a plain message) no longer
shows an empty
<subject>.attachmentsfolder next to it. Its attachments are restored with the message and were never listed; the folder row the backup records for them is now hidden from the listing, the folder tree and search as well. - The job dialog of Proxmox VE: on a phone (390 px) the three restore-point fields stack, so "Monatliche Sicherungsstände" no longer runs over the dialog's edge.
Security
- The setup wizard accepts the Entra tenant for Graph mail only as a tenant id (GUID) or a
verified domain, as Settings already did; anything else is refused (422) before it can reach
the token URL. The URL was never open to another host (the value is URL-encoded, the login
host is fixed), but a value such as
..changed its path. - An IMAP OAuth2 secret is refused unless its
tenantIdis a tenant id, a verified domain,common,organizationsorconsumers, and itstokenEndpointis an https URL. Neither the API nor the UI creates such secrets yet; the token request will also need the address policy of IMAP connections before XOAUTH2 is offered.
Upgrade notes
New images and three database migrations; no new required environment variable, and the
docker-compose.yml of 0.4.0 stays.
- Three database migrations run at the api's start: 0063 adds three nullable columns to the
licensetable, 0064 the removal state of a machine toendpoints(three nullable columns and a partial index over the removals that are due), 0065 the protected object kindgroup(an enum value only). None of them rewrites a table. - Installed licence keys keep working unchanged: every key issued before 0.4.5 is a beta
licence and covers every 0.x and 1.x release. From now on, an image started with a key that
does not cover it stops before the migrations and says so in the log;
RESTOW_RUN_AS_COMMUNITY=1starts it as Community instead (docs/LICENSING.md). - Group mailboxes are opt-in: after the update no group is backed up until the protection rules switch "Protect all Microsoft 365 groups" on or single groups are included. The first directory sync after the update reads the groups of every Microsoft 365 source once in full.
- Rollback to 0.4.4 after the migrations was not tested: take a database backup before the update and restore it to go back.
Known issues
- Group calendars and conversations were tested against a simulated Graph API, never against a
real Microsoft 365 tenant; which calendar reads Graph allows an app on a group can differ by
tenant (the backup falls back to
calendarViewand reports what it could not read). - Machines removed from Restow cannot be restored from in the interface while their backups are kept until expiry.
- IMAP sources with OAuth2 still cannot be created in the API or the interface.
- The known issues of 0.4.4 still apply.
Verification
Before the tag, on the release branch (0.4.4 plus the 0.4.5 workstreams): lint and typecheck of all workspaces, the unit and Postgres suites of every package on Postgres 16 (with the Postgres guard), the web DOM tests, the v1 OpenAPI test, drizzle-kit without drift, the Go tests of the agents, the server installer and demo reset tests and the third-party notices. The release smoke ran on the release branch; no real Microsoft 365 tenant was used before the tag.
Release pipeline, 2026-10-23:
| Check | Result | Duration |
|---|---|---|
| 1. Install: images, compose up, migrations (new install and upgrade) | PASS | 89s |
| 2. Health endpoints, worker and scheduler registered | PASS | 0s |
| 3. Passkey sign-in E2E with a virtual authenticator, tenant creation, i18n de/en | PASS | 2m 06s |
| 4. Microsoft 365 backup and restore against the dev tenant | SKIPPED | 0s |
| 5. IMAP backup and restore against Dovecot, hash comparison | PASS | 8s |
| 6. Journal receipt, chain verification, export | PASS | 3s |
| 7. Standalone restore with restow-restore from the storage of check 5 | PASS | 24s |
| 8. Storage targets: S3 (Garage), local path, mounted directory | PASS | 21s |
| 9. Image scan (Trivy) and dependency audit (pnpm audit) | PASS | 19s |
| 10. Endpoint backup: the agent enrolls, backs up a folder, restores it | PASS | 11s |
| 11. Mail import (folder and upload) and export (EML ZIP, MBOX), compared by hash | PASS | 10s |
| 12. File share backup against Samba: back up, browse, ZIP, restore with permissions, copy job | PASS | 2m 14s |
| 13. Archive capture: IMAP sync with IDLE and backfill, forwarded copies, dedupe, chain | PASS | 2m 09s |
12 of 13 checks passed in full, 0 partly, 1 skipped, 0 failed. The full report, including the reason for every skipped or partial check, is attached to the release as smoke-report.md.
The Community images were smoke-tested on their own (smoke-report-community.md, smoke-report-community-arm64.md): amd64 PASS with gaps: 9 of 13 checks passed in full, 0 partly, 4 skipped (see the reasons below); arm64 PASS with gaps: 9 of 13 checks passed in full, 0 partly, 4 skipped (see the reasons below).
Release-Notes von 0.4.5 auf GitHub ↗
0.4.4 beta · 22. Oktober 2026
Die Release-Notes dieser Version gibt es nur auf Englisch.
Restow 0.4.4 archives mail beyond Exchange journaling (Business): Microsoft 365 mailboxes by Graph change notifications, IMAP and Google Workspace accounts by IMAP sync with IDLE, and the copies a mail provider forwards, each with a one-time takeover of the mail already there and one archived item per mail however many ways captured it. The job editor offers only the capture ways that fit each kind of mailbox, the archive page shows the capture, the hold confirmation, ready-made Exchange Online PowerShell commands and the forwarding addresses, and alerts say when capture stops. The restore explorer opens large mailboxes and OneDrives in milliseconds instead of seconds to minutes; four database migrations (Upgrade Notes). Mail jobs that archived before keep doing exactly that after the update: nothing new starts by itself.
Breaking changes
None. The integration API contract stays at 1.5.0: its archive status and report count
forwarded copies in their totals, but do not list them as a channel of their own yet. In the
session API, mail jobs carry archiveCapture and their members captureKind, and the archive
search hides captures a stronger one superseded unless includeSuperseded=true; a job that
archives without any capture way for a kind of its mailboxes is refused with 422
archive_capture_no_way, which the defaults never cause. The IMAP and Google ways of a job
from before the update may carry pending: true (no way chosen yet): the API accepts such a
job until a way is chosen, keeps the marker only where the job had it, and never sets it.
Added
- Archive capture foundation for mail beyond Exchange journaling (docs/ARCHIVE.md
"Erfassungswege"). A mail job's archive keeps its capture ways per kind of mail object
(
archiveCaptureon create, change and read of a mail job: Microsoft 365 by Graph and/or journaling, IMAP and Google Workspace by IMAP sync and/or a forwarded copy; the defaults of a new job are Graph and IMAP sync, jobs that archived before keep journaling only, see Upgrade Notes). A job that archives needs at least one way for every kind of mailbox it covers (422archive_capture_no_way). Members and candidates carrycaptureKind(m365,google,imap,imap_microsoft), andGET /api/v1/backup-jobs/defaults?kind=mailnames the tenant'smailSourceKinds. - Archive page (Business): a notice that can be put away names the mail jobs where Graph or
IMAP archiving could be switched on, each with a link to the job, and the capture status
lists the jobs whose IMAP or Google Workspace accounts wait for a capture way
(
GET /api/v1/archive/capturereturns them asjobs). - Worker: a capture service keeps one stream per archived mailbox and mailbox way, claimed
across worker processes with
FOR UPDATE SKIP LOCKEDand a lease, reconciled from the mail jobs every two minutes without a job row per mail. Pausing a job stops its scheduled backups only; capture goes on until archiving or the way is switched off in the job. It idles while the edition does not include capture from the mailbox, stops on shutdown and update drain, and pauses a tenant while its storage switches targets. New settingsARCHIVE_CAPTURE_CONCURRENCY(16),ARCHIVE_CAPTURE_TENANT_CONCURRENCY(4) andARCHIVE_BACKFILL_CONCURRENCY(4). Thearchivequeue has a handler: the one-time takeover of a mailbox's existing mail once its stream is live (marked as captured late), and archive schedules of older releases make the named mailboxes due. The Graph and IMAP ways plug into this framework. GET /api/v1/archive/capture(state per capture way: availability, streams, how mail is noticed, counts of 24 hours and 7 days, takeover progress),GET /archive/capture/mailboxes,POST /archive/capture/mailboxes/:objectId/resync(audited asarchive.capture.resync_requested) andGET/PUT /archive/capture/holds/:sourceId, the confirmation that a retention policy or litigation hold keeps deleted mail in a Microsoft 365 tenant (audited asarchive.hold.confirmedandarchive.hold.unconfirmed).- Business: new capability
archive.mailboxCapture; the gated featuresarchive.mailboxCaptureandarchive.smtpCapture(API/meand the worker's newfeaturesextension point).archive.journalReceiveralso covers forwarded copies. - Archive capture of Microsoft 365 mailboxes by Graph (docs/MICROSOFT.md "Archiv-Erfassung per
Graph"): one change notification subscription per archived mailbox (created and renewed in
$batch, at most 20 per request and one request per second and Microsoft tenant; renewed with less than a day left; reauthorized, recreated after removal, after expiry and when the Entra app changes), immutable message ids, notified mail fetched within minutes (drafts skipped), a delta catch-up over every folder and the recoverable deletions with its own state (everyARCHIVE_GRAPH_CATCHUP_MINUTES, default 360, and at once after a missed notification), and the one-time takeover of the existing mail in resumable pages. No new Microsoft permission is needed. Without a public HTTPS URL the mailboxes are polled everyARCHIVE_GRAPH_POLL_MINUTES(default 15) and the capture status names the reason (graph.notification_url_unavailable); a subscription Microsoft refuses is retried hourly meanwhile (graph.subscription_failed). - Public hooks
POST /api/v1/hooks/graph/notificationsand/lifecyclefor Graph: the validation token is echoed, everything else answered 202; only notifications whoseclientStatematches the subscription's stored SHA-256 count, and they only queue a fetch. Bodies are limited to 1 MiB, and the hooks answer 404 while the edition does not include capture from the mailbox. GET /api/v1/archive/capture/holdsalso returnschecks: read-only Exchange Online and Security & Compliance PowerShell commands to check litigation holds and retention policies before confirming a hold. Graph v1.0 offers no way to read them (spike result in docs/MICROSOFT.md).- IMAP archiving (Business; docs/IMAP.md "Archivierung"): the capture way
imap_syncarchives an IMAP account continuously. Activation records where every folder stands, the one-time takeover brings in the mail that was there (resumable, flagged captured late), and every pass reads only new mail: STATUS per folder, metadata first, sources only of mail the archive does not hold for the account yet. All folders but Drafts; on Gmail and Google Workspace only All Mail, Spam and Trash. A changed UIDVALIDITY reads the folder again without archiving anything twice. Up toARCHIVE_IMAP_IDLE_MAX(300) accounts per worker are watched with IMAP IDLE, shared between worker processes through Postgres locks, with a STATUS round over the other folders everyARCHIVE_IMAP_POLL_MINUTES(5); other accounts are polled everyARCHIVE_IMAP_LOGIN_POLL_MINUTES(10). New source settingarchiveIdle(auto,off) for providers with a tight connection limit. Why an account is polled is shown asimap.idle_unsupported,imap.idle_disabledorimap.idle_budget. - Forwarded copies into the archive (Business; docs/IMAP.md "Weiterleitung"): the receiver takes
plain copies a provider forwards (Postfix BCC maps, mailcow, Sieve
redirect :copy, Google Workspace routing) as sourcesmtp_forward, next to Exchange journal reports. Every IMAP account can have its own archive addressarchive+<token>@<journal host>; a copy to it belongs to exactly that account, a copy to the tenant's journal address is assigned by its headers andMAIL FROM. New routesGET /api/v1/archive/forwarding(accounts, addresses, copies of the last 7 days; issues nothing),POST /api/v1/archive/forwarding/:objectId/address(issued once, auditedarchive.forward.address_created) andPOST /api/v1/archive/forwarding/:objectId/rotate(auditedarchive.forward.address_rotated, fingerprints only). GET /api/v1/archive/journalnamesfirstReportAt, the first journal report that arrived.- Release smoke check 13: IMAP archiving with backfill and IDLE, forwarded copies and their dedupe against the synced mail, against the Dovecot of check 5.
- Job editor: the archive's capture ways per kind of mailbox in the job (Microsoft 365: Graph and Exchange journaling; IMAP and Google Workspace: IMAP archiving and forwarding), each labelled as captured at transport or near-time, locked with the edition that has it, at least one per kind; IMAP accounts on a Microsoft host get the hint to connect a Microsoft 365 source instead.
- Archive page: capture from the mailboxes (Graph and IMAP archiving: streams, how mail is
noticed and why a mailbox is checked at intervals, counts, takeover of existing mail), the
capture per mailbox with a catch-up, and the hold confirmation of each Microsoft 365 source
with the Exchange Online PowerShell commands that check it. Search and detail name forwarded
copies, mail captured afterwards and the other ways that captured the same mail again; a
capture replaced by a stronger one is hidden unless asked for (
includeSupersededonGET /api/v1/archive/search), and the detail links both (supersededBy,captures). - Business: Exchange journaling as ready-made Exchange Online PowerShell commands (connector,
mailbox for undeliverable journal reports, journal rule) and a wait for the first report that
checks every 5 seconds. Forwarding to the archive: an address per IMAP account (created,
copied, renewed after a question), its status, and instructions for Postfix and mailcow BCC
maps, Sieve
redirect :copyand Google Workspace routing to the tenant's journal address. - IMAP source page: the archive setting
archiveIdle, IMAP IDLE (automatic) or checks at intervals only, saved at once and locked without the edition that archives from the mailbox. - Exporting the current archive search leaves out the captures a stronger one superseded, as
the search does, so the export holds what the search counted; with superseded captures shown,
the export includes them (
includeSupersededin the export's search filter). - Alerts of the archive capture as
archive.failed(bell, rules, mail): a mailbox whose capture has been in error for more than an hour, an IMAP account whose forwarded copies stopped for 24 hours while its job wants them, and a journal address without reports for 24 hours, each after it received before and once per stretch. The bell and the mail say which of these it is and lead to its section of the archive page.
Changed
- Every archive writer (journal receiver, file import, capture ways) appends through one shared
path. The original is uploaded before the tenant's chain lock is taken, so a large report no
longer holds up the other deliveries of the tenant. Mail captured more than once is recognised
by Message-ID and content: a capture not stronger than what the archive holds becomes a capture
row on that item instead of a second item, a stronger one names the item it supersedes, and the
same Message-ID with another body is kept and flagged
message-id-conflict. Journal reports and imported messages are still stored as items of their own. - The archive record format gains the optional
bodyHashandsupersedesItemIdand the sourcesmtp_forward(packages/core archive/FORMAT.md); records written before stay as they are. - Journal receiver: one SMTP transaction delivers into one tenant's archive; a recipient of a
second tenant is answered 452 and delivered by the sender separately. The limit per sending IP
rises from 60 to 600 connections per minute (
JOURNAL_RATE_PER_IP), and a new limit per archive address (JOURNAL_RATE_PER_ADDRESS, 300 per minute) answers 451. Mail to the journal address that is not a journal report (noX-MS-Journal-Reportheader and not built like one) is archived as a forwarded copy with its own headers' envelope instead of as an incomplete report. - Pausing a mail job stops only its scheduled backups; archiving goes on, and the pause question says so. The forwarding page counts the accounts of a paused job as wanting their forwarded copy. Switching archiving or a capture way off in the editor asks first: new mail of these mailboxes is no longer archived from then on, the archive kept so far stays.
- docs/ARCHIVE.md describes the capture ways of 0.4.4; docs/ARCHITECTURE.md describes the Graph throttling as it is built (no shared token bucket per source).
- Restore explorer: the restore points of an account load alongside its owner's entry instead of after it, one round trip less before a mailbox or OneDrive shows its folders.
- The Proxmox VE job dialog is twice as wide and lays its settings out in two columns from tablet width on (name and schedule with the next runs on the left; scope, restore points, restore check, boot test and guests on the right), so a job's settings fit on a desktop screen without scrolling; on a phone it stays one column at full width.
Fixed
- Opening the job editor of a job with only IMAP accounts no longer creates the tenant's journal address: it is requested only while Exchange journaling is chosen for Microsoft 365 mailboxes.
- The archive chain could fork when two writers of one tenant stamped their items with the same time: the predecessor was taken by time alone. Writers now take the last item in the order the chain check walks (time, then id) and stamp their item strictly later.
- Restore explorer: opening a large mailbox or OneDrive no longer takes seconds to minutes
before its folders show. Every folder listing read all entries of the restore point (every
message of the mailbox, every file of the OneDrive, with their metadata), twice per request,
and matched the folders below against them without an index; a folder whose subfolders
have no entry of their own (the mailbox root with
mailandcalendar, a OneDrive root) grew with the square of the entries and could time out. The listing now reads the folder's children and the folders below it from two new indexes (migration0061_explorer_parent_index; on a largemanifest_versionstable the update takes longer, docs/UPDATING.md): with 120 000 messages and 200 000 files, the mail folder list went from 2.5 s to 15 ms, the root of the mailbox and of the OneDrive from over a minute to 15 ms, and every OneDrive folder from 1.5–2.5 s to about 10 ms. A folder of 50 000 messages lists its first page in about 0.5 s (was 1.9 s). Restore points of 0.3.4 and earlier that the worker has not converted yet are listed as before. - Restore explorer: the versions OneDrive kept of a file and the calendar's month view read the same indexes instead of every entry of the restore point (130 ms and 260 ms to under 50 ms for the sizes above).
- Mail preview, attachment download and calendar series: each chunk of the message is read from storage with a byte-range request for exactly its bytes instead of downloading its whole pack (up to 64 MiB) for every preview; a chunk damaged on every target is still read through its whole pack as before. The archive's content check reads the same way.
Upgrade notes
New images and four database migrations; no new required environment variable, and the
docker-compose.yml of 0.4.0 stays.
- Migrations 0059 to 0062 run at the api's start: the capture tables, new columns and five
indexes on
archive_itemsandbackup_jobs, two indexes onmanifest_versionsfor the restore explorer, and the capture ways of the mail jobs that already archive (below). The indexes are built inside the migration, where writes to the table wait; expect about a minute per ten million rows on SSD storage. Countarchive_itemsandmanifest_versionsbeforehand and plan a large installation's update outside the backup window (docs/UPDATING.md). - Capture from the mailbox needs the capability
archive.mailboxCapture. Capabilities follow the license's edition (ee/licensing), so every Business and Service Provider license includes it without a new key; the Community build keeps the capture service idle. - Mail jobs that archive keep doing exactly what they did before the update: migration 0062 gives each of them Exchange journaling only for Microsoft 365 mailboxes and no capture way yet for IMAP and Google Workspace accounts (marked as waiting for a choice), so no capture and no takeover of existing mail starts by itself. An administrator switches Graph or IMAP archiving on in the job; the job editor says at the IMAP card that no way is chosen yet, the archive page names the jobs where a way could be switched on (with a notice that can be put away, Business only), and the capture status lists the jobs waiting for a choice. Edits that do not touch the ways (name, schedule) save as before. Jobs created after the update, and a job that switches archiving on, start with the defaults: Graph for Microsoft 365 mailboxes, IMAP sync for IMAP and Google Workspace accounts, each with a one-time takeover of the mail already in the mailbox (marked as captured late).
- Graph capture is notified of new mail only when the installation's public URL is
https://on port 443 and reachable from Microsoft (/api/v1/hooks/graph/*; a reverse proxy of your own must pass it through, with at most 1 MiB per request). Otherwise every mailbox is polled everyARCHIVE_GRAPH_POLL_MINUTES(15) and the capture status says why. No new Microsoft permission is needed. - IMAP archiving keeps one connection per account open (IDLE) where the server offers it.
For providers with a tight connection limit, set the source to "Check at intervals only"
(
archiveIdle: "off"). - New optional settings: the journal receiver's
JOURNAL_RATE_PER_IP(now 600 per minute, was a fixed 60) andJOURNAL_RATE_PER_ADDRESS(300), and the capture'sARCHIVE_CAPTURE_CONCURRENCY,ARCHIVE_CAPTURE_TENANT_CONCURRENCY,ARCHIVE_BACKFILL_CONCURRENCY,ARCHIVE_GRAPH_CATCHUP_MINUTES,ARCHIVE_GRAPH_POLL_MINUTES,ARCHIVE_IMAP_IDLE_MAX,ARCHIVE_IMAP_POLL_MINUTESandARCHIVE_IMAP_LOGIN_POLL_MINUTES(.env.example). - Rollback to 0.4.3 after the migrations was not tested: take a database backup before the update and restore it to go back.
Known issues
- Graph capture was tested against a simulated Graph API, IMAP archiving against a simulated IMAP server and the Dovecot of the release smoke, forwarding against the receiver itself; never against a real Microsoft 365 or Google Workspace tenant, Postfix, mailcow or hoster.
- Holds in a Microsoft 365 tenant are not detected: Graph v1.0 offers no way to read them, so an administrator confirms them per source. Of the Recoverable Items only the deletions folder is read; mail purged before Restow fetched it can be missing. Graph cannot export mail over about 150 MB; such mail is logged, not archived.
- The receiver does not check the sender (SPF), and its limits count per api process.
- IMAP sources with OAuth2 still cannot be created in the API or the interface, so a Google Workspace account is recognised by its host or folder list only.
- The integration API's archive status and report do not list forwarded copies as a channel of their own (see Breaking Changes).
- The known issues of 0.4.3 still apply.
Verification
Before the tag, on the release branch (0.4.3 plus the 0.4.4 workstreams): lint and typecheck of all workspaces, the unit and Postgres suites of every package on Postgres 16 (with the Postgres guard), the web DOM tests on happy-dom including the layout-width and green-is-proof checks, the v1 OpenAPI test, drizzle-kit without drift, gofmt, go vet and the Go tests of the agents, the Perl tests of the Proxmox VE plugin, the server installer and demo reset tests, shellcheck, the CI script tests, the smoke runner's unit tests and the third-party notices. The release smoke, including the new check of the archive capture against Dovecot, runs in the release pipeline; no real Microsoft 365 tenant, Google Workspace or mail provider was used before the tag.
Release pipeline, 2026-10-22:
| Check | Result | Duration |
|---|---|---|
| 1. Install: images, compose up, migrations (new install and upgrade) | PASS | 94s |
| 2. Health endpoints, worker and scheduler registered | PASS | 0s |
| 3. Passkey sign-in E2E with a virtual authenticator, tenant creation, i18n de/en | PASS | 2m 06s |
| 4. Microsoft 365 backup and restore against the dev tenant | SKIPPED | 0s |
| 5. IMAP backup and restore against Dovecot, hash comparison | PASS | 8s |
| 6. Journal receipt, chain verification, export | PASS | 3s |
| 7. Standalone restore with restow-restore from the storage of check 5 | PASS | 24s |
| 8. Storage targets: S3 (Garage), local path, mounted directory | PASS | 21s |
| 9. Image scan (Trivy) and dependency audit (pnpm audit) | PASS | 23s |
| 10. Endpoint backup: the agent enrolls, backs up a folder, restores it | PASS | 12s |
| 11. Mail import (folder and upload) and export (EML ZIP, MBOX), compared by hash | PASS | 8s |
| 12. File share backup against Samba: back up, browse, ZIP, restore with permissions, copy job | PASS | 2m 30s |
| 13. Archive capture: IMAP sync with IDLE and backfill, forwarded copies, dedupe, chain | PASS | 117s |
12 of 13 checks passed in full, 0 partly, 1 skipped, 0 failed. The full report, including the reason for every skipped or partial check, is attached to the release as smoke-report.md.
The Community images were smoke-tested on their own (smoke-report-community.md, smoke-report-community-arm64.md): amd64 PASS with gaps: 9 of 13 checks passed in full, 0 partly, 4 skipped (see the reasons below); arm64 PASS with gaps: 9 of 13 checks passed in full, 0 partly, 4 skipped (see the reasons below).
Release-Notes von 0.4.4 auf GitHub ↗
0.4.3 beta · 22. Oktober 2026
Die Release-Notes dieser Version gibt es nur auf Englisch.
Restow 0.4.3 stops a locked repository from failing a Proxmox VE restore check (it is postponed and, if the lock stays, reads "Could not check" in amber with who holds the lock) and tidies VMs & containers up into tabs with search, filters, a detail panel and tables that no longer jump while backups run. Proxmox VE nodes and agents follow a server update even when its announcement went unanswered, "Update nodes and agents now" starts that step by hand, and restow-pve restarts the PVE daemons after it updates itself. No database migration; nodes still on restow-pve 0.4.1 need one update by hand (Upgrade Notes).
Breaking changes
None. The integration API contract stays at 1.5.0. In the session API, a Proxmox VE guest's
lastVerify.state can be yellow (with notChecked) and a node carries offeredVersion
and outdated; both are additive.
Added
- Updates tab: Update nodes and agents now on the card of nodes and agents. When the
server runs a newer release than its Proxmox VE nodes and agents but no update led into the
step where they follow it (an update by hand, or one whose announcement went unanswered),
an administrator with every tenant starts that step: new runs pause for at most 15 minutes,
reachable nodes and agents install the release when idle, and the pause ends once they are
done (
POST /api/v1/updates/fleet/update-now, audited asupdate.fleet_startedwithmanual: true). Outside an update, nodes and agents that are behind show as "Update available". - Proxmox VE inventory (
GET /api/v1/pve): every node carriesofferedVersion(the restow-pve release the server offers) andoutdatednext to itshelperVersion. - Releases publish the two images of the public demo as well (
restow-demo-seedandrestow-demo-dovecot, amd64 and arm64, signed, with SBOMs and the release's tags), anddeploy/demo/reset.shcan follow a channel or a fixed version (RESTOW_DEMO_FOLLOWindeploy/demo/.env): the nightly reset pulls the images of one release and stops before it changes anything when they do not match or a pull fails (deploy/demo/README.md).
Changed
- VMs & containers is tidied up into three tabs with counts: Guests (the default), Backup
jobs and Nodes. The note that the Proxmox VE host itself is not backed up is one line on the
Nodes tab and can be hidden. The Nodes tab shows each node's heartbeat, its restow-pve
version with "Update to …" when the server offers a newer release (
outdated), its Proxmox VE version, how many guests it has, its queue and its problems; queue control and revoking are in the row menu. - The guests table has a search over ID and name, filters by node, kind (VM or container), backup job (also "No backup job") and state, a "Problems only" button (failed, warnings or gaps, a restore check that failed or could not run, waiting for a disconnected or paused node, not backed up), sortable columns (ID, name, node, last backup, backup size, state), pages of 25 to 250 guests and the count of what the filters leave. Tab, search, filters, order, page and the open guest live in the address, so a link opens the same view.
- A guest's row shows one state badge, chosen by priority, with a small progress bar while its backup runs or "+N" for further problems. Clicking the row (or its name) opens a detail panel with every state, the complete error and warnings of the last run in a scrollable, copyable block, the restore check with what it found (or, when a locked repository kept it out, who holds the lock, amber), the backup sizes, the backup job, the newest runs and the actions (back up now, stop, withdraw, check now, open the guest page).
- The Backup column says how large a guest's first (full) backup was and what the last follow-up added, for example "First: 32 GB on Oct 3 · Last: +210 MB"; the detail panel shows the new data of each of the last 30 backups as small bars (#58).
- The README screenshots show 0.4.2, with two new views (the mail archive and a server).
- Development: the web tests run on happy-dom 21.
Fixed
- Proxmox VE: right after a container backup, the new restore check often failed with
restic check failed (exit code 11) the "unlock" command can be used to remove stale locksand the guest showed a red "Restore check failed", although the check never ran: another run (usually the guest's own backup, whose lock a cancel or an API restart had left behind) held the repository's lock. A check a lock keeps out is no longer a failed check: it is tried again ten minutes later, the previous result standing, and after two hours the restore point reads "Could not check: repository locked" (yellow, attention, never red or green) with restic's report of who holds the lock. The worker removes stale restic locks before the check and before retention, restic waits up to two minutes for a lock during the check and up to 15 minutes during the container backup (restow-pve), a guest is not checked while a run of it is going or its node took on a backup of it, and a new restore point is checked two minutes after its commit at the earliest. A cancelled or ended run may still delete its own restic lock (every other request of it is refused and audited). A failed check keeps restic's explaining lines, not only its last one. No database migration. - Updates: announcing an update could report "The updater is not running" although the
updater accepted it a few seconds later. The api waited 5 seconds for an answer while the
updater checks Docker, the Compose configuration, the disk space and the running version
first (5 to 12 seconds on real installations). The update then ran without the pause of new
runs, without the
update.scheduledaudit entry and without the step in which Proxmox VE nodes and agents follow the server, so they stayed on the old release. The api now waits up to a minute for the announcement (30 seconds for cancelling, dismissing, restarts and deleting a dump); when the answer is still lost it reads the updater's state again and treats the update as accepted when the updater shows it. The pause is lifted only on a clear refusal or an idle updater, and "Start now" after waiting for runs no longer sends a false failure notification. The updater answers faster: it checks once per announcement and reuses the measured database and image sizes of the last ten minutes (the run's first step measures again). The Updates tab reads the state again after a failed announcement and says it is checking whether the update was accepted instead of "not running". - Updates: the Updates tab could say "The updater is not running" for a few seconds every now and then. When the updater's check of the last 30 seconds had expired, it checked again before it answered (several short-lived helper containers), which could take longer than the 5 seconds the api waits for the state, and the api then remembered "no updater" for 8 seconds. The updater now answers at once with its last check and checks again in the background (an update still checks anew before it starts), and a plain state read that times out keeps the updater's last state for up to 30 seconds after its last answer.
- Proxmox VE: after a self-update (automatic, "update now" or
restow-pve update) the PVE daemons kept the old storage plugin loaded until they restarted. restow-pve now restarts pvedaemon, pveproxy, pvestatd and pvescheduler like the installer does (systemctl reload-or-restarton the running ones; a failure is logged and does not undo the update).restow-pve updatealso restarts the running restow-pve service, so the node reports the new release with its next heartbeat. A node that an older restow-pve updated restarts the daemons once by itself (it remembers the plugin files it restarted them for). - VMs & containers no longer jumps while backups run: the guest and job tables keep fixed column widths and one row height (loading rows included), long texts are cut to one line instead of wrapping, the progress has a reserved slot, and "Back up now", "Stop", "Withdraw" and "Stopping…" share one button size. Error texts no longer appear in red under a guest's row, and warnings no longer only in a tooltip.
- Demo: during the nightly reset the demo shows a short page in English and German that reloads every minute, instead of a 502. After signing in, the overview opens on a customer tenant instead of the empty provider organization, and the simulated machines report the running release as their agent version instead of 0.2.1.
Upgrade notes
New image, no database migration, no new required environment variables, and the
docker-compose.yml of 0.4.0 stays.
- Proxmox VE nodes should run restow-pve 0.4.3: it waits for the server's repository lock
during a container backup and restarts the PVE daemons after it updates itself. Nodes on
restow-pve 0.4.2 install it with the step after the server update (or "Update nodes and
agents now"). Nodes on restow-pve 0.4.1 ignore "update now" and that step; they update with
their own check (two minutes after the service starts, then every six hours), or by hand
once no backup or restore runs on the node:
/opt/restow-pve/bin/restow-pve update, thensystemctl restart restow-pve pvedaemon pvestatd pveproxy pvescheduler. From 0.4.3 on restow-pve restarts the daemons itself; a node that an older release updated does it once after the new release starts. - Restore checks that a locked repository failed before the update stay red until the next check of the guest ("Check now" on the guest or VMs & containers).
- Demo hosts: the demo images are now published with every release; to let the demo follow
them, set
RESTOW_DEMO_FOLLOWas deploy/demo/README.md describes. - Rollback: 0.4.2 starts on the same database. It shows a restore point that could not be checked as unchecked.
Known issues
- The new parts were tested against a simulated Proxmox VE API and S3 store only, never against a real Proxmox VE cluster or S3 provider.
- The redesigned VMs & containers page was tested with DOM tests, not visually in a browser with thousands of guests.
- The known issues of 0.4.2 still apply, except the file share repository healing, which comes later.
Verification
Before the tag, on the release branch (main plus the 0.4.3 workstreams): lint and typecheck of all workspaces, the unit and Postgres suites of every package on Postgres 16 (with the Postgres guard), the web DOM tests on happy-dom 21 including the layout-width and green-is-proof checks, the v1 OpenAPI test, gofmt, go vet and the Go tests of the agents, the Perl tests of the Proxmox VE plugin, the server installer and demo reset tests, and shellcheck. The release smoke runs in the release pipeline; no real Proxmox VE cluster or S3 provider was used before the tag.
Release pipeline, 2026-10-22:
| Check | Result | Duration |
|---|---|---|
| 1. Install: images, compose up, migrations (new install and upgrade) | PASS | 87s |
| 2. Health endpoints, worker and scheduler registered | PASS | 0s |
| 3. Passkey sign-in E2E with a virtual authenticator, tenant creation, i18n de/en | PASS | 2m 15s |
| 4. Microsoft 365 backup and restore against the dev tenant | SKIPPED | 0s |
| 5. IMAP backup and restore against Dovecot, hash comparison | PASS | 8s |
| 6. Journal receipt, chain verification, export | PASS | 3s |
| 7. Standalone restore with restow-restore from the storage of check 5 | PASS | 24s |
| 8. Storage targets: S3 (Garage), local path, mounted directory | PASS | 20s |
| 9. Image scan (Trivy) and dependency audit (pnpm audit) | PASS | 21s |
| 10. Endpoint backup: the agent enrolls, backs up a folder, restores it | PASS | 11s |
| 11. Mail import (folder and upload) and export (EML ZIP, MBOX), compared by hash | PASS | 8s |
| 12. File share backup against Samba: back up, browse, ZIP, restore with permissions, copy job | PASS | 2m 17s |
11 of 12 checks passed in full, 0 partly, 1 skipped, 0 failed. The full report, including the reason for every skipped or partial check, is attached to the release as smoke-report.md.
The Community images were smoke-tested on their own (smoke-report-community.md, smoke-report-community-arm64.md): amd64 PASS with gaps: 9 of 12 checks passed in full, 0 partly, 3 skipped (see the reasons below); arm64 PASS with gaps: 9 of 12 checks passed in full, 0 partly, 3 skipped (see the reasons below).
Release-Notes von 0.4.3 auf GitHub ↗
0.4.2 beta · 21. Oktober 2026
Die Release-Notes dieser Version gibt es nur auf Englisch.
Restow 0.4.2 stops a running backup from the web app (Proxmox VE, servers and clients,
file shares) and lets Proxmox VE nodes and agents follow a server update before new runs
start. A container whose repository went missing after a storage change begins a new
backup chain instead of failing, and a storage "move" now copies the restic repositories
of containers, machines and file shares. Every new Proxmox VE restore point is checked
within minutes of its backup. The storage check tells a pack it could not read for the
moment (a transfer or permission error) from a damaged one. The restore explorer lists one
entry per person and shows a mailbox's calendar by month; the mail job editor asks first
whether a job backs up, archives or both. The installation has a time zone of its own, and
restow-agent update installs the offered agent release at once. Six database migrations.
Breaking changes
None. The public API's storageIntegrity.state has the new value unreadable (integration
API contract 1.5.0, additive); clients that handle its values exhaustively should accept
it. "Keep existing backups where they are" is refused while containers or file shares have
restic repositories (see Fixed and Upgrade Notes).
Added
- Proxmox VE: "Reset repository" for a container (guest page, danger zone): the guest's name
typed, a recent sign-in, audited (
pve.repository.reset). Its restore points become unavailable at once and the next backup begins a new chain (POST /api/v1/pve/guests/:id/repository/reset). - Where backups land:
GET /api/v1/storage/destinationnames the tenant's effective primary repository. The guest page and its new "Back up now" dialog, the PVE job and connect dialogs, a machine's and a file share's page and the job editors show it; the installation default on the server's local disk is highlighted. The Repositories section and the dialogs that add PVE nodes, machines and file shares warn "Backups land on the server's own disk" when the primary is a directory on a disk of the server itself (not a network share). - Proxmox VE: every new restore point is checked within minutes of its backup, a bounded
number per pass, besides the weekly check of every guest. Installation › Proxmox VE has the
setting "Check every new restore point right after the backup" (on by default;
GET/PUT /api/v1/settings/pve). One database migration. - Proxmox VE in Recovery readiness: "Check now" per guest and "Check all unverified"
(
POST /api/v1/pve/guests/:id/verify,POST /api/v1/pve/verify-unverified); the footer names the Microsoft 365 schedule as such and says how VMs and containers are checked. - Proxmox VE backup jobs take the cadences of a mail job: every few hours, daily, on chosen weekdays, monthly or a cron expression (not more often than hourly).
- The Restow server's own VM: found by its SMBIOS UUID (restow-pve 0.4.2 reports it with the inventory) or marked by an admin on the guest's page. It is marked in the lists and the job editor, no job backs it up, and "Back up now" and putting it into a job need a confirmation that names the self-backup risk (docs/PVE.md, "The Restow server's own VM").
- Stop a backup from the web app, without SSH on the node. Proxmox VE: Stop in the VMs & containers table, on the guest's page and in the run drawer withdraws a queued backup at once and stops a running one: restow-pve now keeps its heartbeat going while a backup runs, gets the cancel order with it and stops the vzdump task through the PVE API (a backup started in PVE: its provider). The run ends cancelled, not failed, and shows "Cancelled by ". Per node: Pause queue (no new backup starts until resumed) and Cancel all queued, also for the whole tenant. Servers and clients: Stop backup on the machine's page and in the run drawer; the agent stops restic cleanly with its next heartbeat (every minute while it backs up). Runs of file shares can now be cancelled from the run drawer as well (Microsoft 365 and IMAP runs already could). Every stop asks first and is audited.
- Nodes and agents follow a server update: after the server runs the new release, new runs stay paused while Proxmox VE nodes and agents install it (they are idle then), until every reachable one reports it or 15 minutes have passed. The Updates tab shows their progress and, for the ones not reached, the command for an update by hand. Update to on a node and on a machine asks for the update at any time.
- Updates can be planned for a chosen date and time (in the installation's time zone) besides the lead times from now; nothing pauses before, and everyone sees a notice from a day before.
restow-agent updateon a machine, likerestow-pve updateon a node: it installs the release the server offers right away, through the same signed download as the automatic self-update, restarts the service and says what it did; while a backup runs it refuses and the agent updates itself once idle. The Updates tab names it for agents that were not reached (and the service restart for agents before 0.4.2).- The installation has a time zone of its own: chosen in the setup wizard (the browser's zone
preselected) and changed by an owner under Installation › Server & operation › Server, with
a searchable list of zones. Planned updates are read in it and a new tenant starts with it.
Without a choice,
RESTOW_TIME_ZONE, thenTZ, then Europe/Berlin apply as before. - When an update is available, the version in the sidebar becomes a highlighted, gently pulsing Update to available that leads to Installation › Updates (for those who may install updates; no animation with reduced motion).
- Restore explorer: a mailbox's calendar has a month view, day by day across all its calendars
or one, and a series in the list opens onto its occurrences, derived from the stored pattern
with the changed occurrences in place (new
GET /api/v1/snapshots/:id/calendar, audited assnapshot.calendar.read). - Restore explorer: one entry per person. A person's mailbox, OneDrive and IMAP account are
grouped; the second column shows Mail, Calendar, Contacts and OneDrive, each with its own
restore points. SharePoint and Teams sites have a section of their own, an orphaned OneDrive
is listed under its owner's name as "Account deleted". The list comes a page at a time from
the new
GET /api/v1/snapshots/people(keyset paging, search over names, addresses and account ids, type filter, all in the database), so tenants with 10,000+ people never load everyone at once. The snapshot objects carryownerKeyandownerName. - Mail job editor: the first question is what the job should do, back up, archive or both (both is the default for a new job). While it archives, the editor names the capture (Exchange journaling) with the way to its setup and suggests backing up every 8 hours; backing up alone names the gap between two runs.
Changed
- A red restore check of a guest shows the error it found (for example restic's) in the guest list, Recovery readiness and on the guest page, instead of only "blocks did not match or could not be read".
- /virtualization: the State column keeps its width and height while a backup reports progress; long messages are cut, with the whole text in the tooltip.
- Storage integrity: a pack the storage check could not read (a download cut off
mid-transfer, a reset connection, a timeout, S3 asking to slow down, or denied access) is
no longer shown or rated as damaged. Recovery readiness › Storage integrity lists it as
"temporarily unreadable" with the error, how many consecutive checks could not read it,
and when first and last; every later check reads it first, and "Re-check these packs"
reads only the flagged packs again. Objects using it are rated "Attention"; they become
"Not restorable" only when a pack is proven damaged (missing, wrong size or checksum) or
could not be read in 3 consecutive checks over at least 24 hours. When the packs read
intact again, the storage finding ends and the object's restore checks rate it again. The
public API's
storageIntegrity.statehas a new value,unreadable. - A run that was stopped on request is
cancelled(machines: a new run and task status); it raises no failure alert and does not count as the last backup. - Database: index
protected_objects (tenant_id, user_id)for a person's objects. - Restore explorer: calendar events sort by when they start (newest first, or upcoming first) instead of by subject, with When, Location and Organizer columns.
- Exchange backup: an event's metadata records its location and the end of a series range.
Fixed
- Proxmox VE: after the primary repository changed with "keep existing backups where they
are", every container with an existing repository failed with
repository does not exist(exit 10): the server trustedrepository_ready_atand never checked the repository was on the new primary. Before a backup gets its restic credential the server now checks it (once per run). Missing everywhere, a new repository and a new backup chain begin, visible on the guest page ("New backup chain started on …: the previous repository was not found at …") and in its history, audited aspve.repository.reinitialized; the earlier restore points become unavailable (no restore, no check, not counted for readiness, skipped by retention). Still on a retired target, the backup is refused with a clear message instead. Restores read the repository from whichever target holds it. One database migration. - Storage: "Keep existing backups where they are" and promoting a copy are refused
(
storage-switch-blocked-by-repositories; the dialog offers "keep" disabled) while containers or file shares have restic repositories, which only "move" takes along. - Storage: a "move" now copies the restic repositories of containers, machines and file shares (from the target that holds each one), verified by size and by SHA-256 like packs, waits for running container backups and file share runs before it switches, and retention of containers and file shares waits for it. It also copies the manifests of VM and container restore points, which it treated as pruned before. A retired location is no longer removable while it alone holds a container's or file share's repository.
- Proxmox VE backups ended with "TASK WARNINGS: 1" and restow-pve reported them as failed although the restore point was committed: restow-pve asks vzdump for no notes any more, the storage plugin takes a notes update as a no-op, and a backup vzdump ends with warnings after its restore point was committed counts as "Succeeded with warnings".
- restow-pve's late task result was refused with "404 Task not found" once the server had closed the task (by the run's own end, the worker, or its expiry during an outage): the server takes it and settles the run (a committed restore point always counts as succeeded), a task whose run is still open no longer expires, and restow-pve keeps a result the server could not take and sends it again with the next heartbeat instead of losing it.
- The storage check read each pack once: a download that broke off mid-transfer (Node's "aborted", which the S3 client does not retry) made a ~65 MB pack "unreadable", the page said "2 packs are damaged … No intact copy exists in any repository", and the mailbox was rated "Not restorable" although a restore check read 20 of 20 items back byte-exact. The check now reads a pack again after a transfer error, whole, up to 3 times (2 s and 8 s apart), hashing as it streams into a buffer of the pack's recorded size. Reads from S3 (restores and restore checks included) resume a body that breaks off from the first missing byte, pinned to the object's ETag.
- The maintenance and update banner covered the top of pages that size themselves to the window: the layout now accounts for the banner's height, also when it wraps to several lines.
- The update progress said "Downloading {image}" (and "{file}", "{services}"): those steps now name the version instead of a placeholder the updater never fills.
- Switching the tenant on a job's page opens the jobs of that kind in the new tenant instead of saying that the job does not exist; any detail page gives way to its list.
Upgrade notes
New image and six database migrations, which run in seconds whatever the size of the installation:
0053_pve_repository_chains: a container's new backup chains (pve_guests.repository_chains) andpve_snapshots.unavailable_at.0054_pve_runs_042: the Restow server's own VM (pve_guests.restow_server_detected,restow_server_flagged,self_backup_confirmed_at),pve_snapshots.verify_requested_atand the installation's Proxmox VE settings (settings.pve_settings).0055_pack_read_failures: a new, empty table. Packs an earlier storage check reported unreadable count as temporarily unreadable after the update and are read again first by the next check; no full check is needed.0056_cancel_and_fleet_update: cancel requests andcancelledstates for tasks and runs, a node's paused queue, "update now" for nodes and machines, the phasefleetof the job-start pause,settings.planned_update.0057_explorer_people: an index on the protected objects of a person in a tenant, for the restore explorer's list of people.0058_installation_time_zone:settings.time_zone. An existing installation has no time zone of its own after the update:RESTOW_TIME_ZONE, elseTZ, else Europe/Berlin applies until an owner chooses one under Installation › Server & operation › Server (docs/UPDATING.md, "The installation's time zone").
No new required environment variables, and the docker-compose.yml of 0.4.0 stays.
- Proxmox VE nodes should run restow-pve 0.4.2: it reports the Restow server's own VM, keeps its heartbeat going while a backup runs (for Stop and the progress) and no longer reports backups with "TASK WARNINGS" as failed. The fleet update after the server update installs it on every reachable node; the Updates tab names the command for the others.
- Stopping a running backup needs restow-pve 0.4.2 on the node and agent 0.4.2 on the machine; an older node ends a cancelled backup at its next upload (the server refuses it), an older agent finishes it. Both update themselves with this release.
- "Keep existing backups where they are" (and promoting a copy) is refused while containers or file shares have restic repositories; change the primary repository with "move", which now takes them along.
- Storage check reports from before 0.4.2 are read again: packs they listed as unreadable count as temporarily unreadable, not damaged, and the next check reads them first. An object rated "Not restorable" only because of such a pack is rated "Attention" until that check.
- Integration API contract 1.5.0 (additive):
storageIntegrity.statecan beunreadable. - Rollback: the migrations only add a table, columns, indexes and enum values and widen a
check; 0.4.1 starts with them, but runs and tasks in the state
cancelledare unknown to it.
Known issues
- A file share whose repository went missing after a storage change is not yet healed the way a container's is (a new backup chain); this comes in 0.4.3.
- The fix for the maintenance and update banner covering the top of window-sized pages was not verified visually in a browser.
- The new parts were tested against a simulated Proxmox VE API, S3 store and Microsoft Graph API only, never against a real Proxmox VE cluster, S3 provider or Microsoft 365 tenant.
- The restore explorer's list of people groups the tenant's protected objects in the database for every page it serves; that is fine up to about 10,000 people per tenant and slower beyond.
- The known issues of 0.4.1 still apply.
Verification
Before the tag, on the release branch (main plus the 0.4.2 workstreams): lint and typecheck of all workspaces, the i18n tests, the server installer tests, the v1 OpenAPI test, gofmt, go vet and the Go tests of the agents, the Perl tests of the Proxmox VE plugin, and the unit and Postgres suites of every changed package on Postgres 16. The release smoke runs in the release pipeline; no real Proxmox VE cluster, S3 provider or Microsoft 365 tenant was used before the tag.
Release pipeline, 2026-10-21:
| Check | Result | Duration |
|---|---|---|
| 1. Install: images, compose up, migrations (new install and upgrade) | PASS | 92s |
| 2. Health endpoints, worker and scheduler registered | PASS | 0s |
| 3. Passkey sign-in E2E with a virtual authenticator, tenant creation, i18n de/en | PASS | 2m 07s |
| 4. Microsoft 365 backup and restore against the dev tenant | SKIPPED | 0s |
| 5. IMAP backup and restore against Dovecot, hash comparison | PASS | 8s |
| 6. Journal receipt, chain verification, export | PASS | 3s |
| 7. Standalone restore with restow-restore from the storage of check 5 | PASS | 25s |
| 8. Storage targets: S3 (Garage), local path, mounted directory | PASS | 20s |
| 9. Image scan (Trivy) and dependency audit (pnpm audit) | PASS | 20s |
| 10. Endpoint backup: the agent enrolls, backs up a folder, restores it | PASS | 12s |
| 11. Mail import (folder and upload) and export (EML ZIP, MBOX), compared by hash | PASS | 10s |
| 12. File share backup against Samba: back up, browse, ZIP, restore with permissions, copy job | PASS | 2m 15s |
11 of 12 checks passed in full, 0 partly, 1 skipped, 0 failed. The full report, including the reason for every skipped or partial check, is attached to the release as smoke-report.md.
The Community images were smoke-tested on their own (smoke-report-community.md, smoke-report-community-arm64.md): amd64 PASS with gaps: 9 of 12 checks passed in full, 0 partly, 3 skipped (see the reasons below); arm64 PASS with gaps: 9 of 12 checks passed in full, 0 partly, 3 skipped (see the reasons below).
Release-Notes von 0.4.2 auf GitHub ↗
0.4.1 beta · 16. Oktober 2026
Die Release-Notes dieser Version gibt es nur auf Englisch.
Restow 0.4.1 counts the restic repositories of machines, file shares and Proxmox VE containers in the stored bytes, instead of the chunk store alone, and says when a running container backup shows no progress because its node runs an older restow-pve. One database migration.
Breaking changes
None. physicalBytes of GET /status and of usage in GET /storage now include the
restic repositories (see Fixed); the fields and their types stay.
Changed
- Repositories › Usage: the chart is called "Chunk store per day", and its note says that the restic repositories keep no history and are not part of the growth.
Fixed
- Repositories › Usage, the Stored tile of the dashboard, the statistics and
GET /statusandGET /storageof the API counted only the packs of the chunk store: a tenant with 10 GB of container backups saw "Stored 10.9 kB" and "0 B backed up". Stored now adds the restic repositories of machines, file shares and Proxmox VE containers, and the usage card shows how much of it is in the chunk store and how much in restic repositories. The deduplication saving, the growth and the chart stay figures of the chunk store, and say so; "Protected data" names the sources it does not include instead of "No completed backup yet". The dashboard tile lists the repositories on a line of their own instead of "0 B backed up". - The size of a container's restic repository was not recorded. The restic route now measures it once at the first upload after the update, then counts every upload and deletion, and the worker measures it again after a prune. A view never lists a repository (it may live on NFS).
- A running container backup on a node with restow-pve before 0.4.0 showed "No progress reported yet" for its whole run. It now says that progress needs restow-pve 0.4.0 on that node, which version the node runs, and to update the node.
- restow-pve asked for an update only six hours after it started, so a restarted node kept an old version for hours. It now asks two minutes after the start, then every six hours; the update still waits until no backup or restore runs.
Upgrade notes
New image and one database migration, 0052_pve_guest_repository_bytes
(pve_guests.repository_bytes and repository_measured_at), which runs in seconds. No new
required environment variables, and the docker-compose.yml of 0.4.0 stays.
- The repository of a container counts under Stored from its next backup on, of a machine or file share as before (from its next backup or retention run); until then it counts as zero.
- Nodes pick up restow-pve 0.4.1 by themselves, within two minutes of their next start or within six hours, while no backup runs.
- Rollback: the migration only adds two columns; 0.4.0 runs with them.
Known issues
- A repository's size has no history: the statistics count the current size of a restic repository at every moment of a period since its machine, share or container was added, so the growth of Stored there comes from the chunk store only.
- Uploads that finish while the first measurement of a repository lists it may be left out until the next prune or retention run measures it again.
- "Protected data" still counts the chunk store's sources only; the logical size of restic backups is not added up.
- The known issues of 0.4.0 still apply.
Verification
Before the tag, on the release branch (main plus the 0.4.1 fixes): lint and typecheck of all workspaces, the server installer tests (679), gofmt, go vet and the Go tests of the agents, and the full unit and Postgres suites on Postgres 16: packages/db 195, packages/i18n 273, packages/core 2311 (6 skipped), apps/scheduler 73, apps/api 3816 (5 skipped), apps/web 4124, apps/worker 529, ee/api 247, ee/licensing 59, ee/web 176, ee/worker 5, packages/cli 34, the demo seed 208; 141 Postgres test files, none skipped. A container backup with the real restic binary checked the size the restic route counted against the repository. The re-measurement after a prune ran in no test with a real repository. The release smoke runs in the release pipeline; no Microsoft 365 tenant was used before the tag.
Release pipeline, 2026-10-16:
| Check | Result | Duration |
|---|---|---|
| 1. Install: images, compose up, migrations (new install and upgrade) | PASS | 91s |
| 2. Health endpoints, worker and scheduler registered | PASS | 0s |
| 3. Passkey sign-in E2E with a virtual authenticator, tenant creation, i18n de/en | PASS | 2m 08s |
| 4. Microsoft 365 backup and restore against the dev tenant | SKIPPED | 0s |
| 5. IMAP backup and restore against Dovecot, hash comparison | PASS | 9s |
| 6. Journal receipt, chain verification, export | PASS | 3s |
| 7. Standalone restore with restow-restore from the storage of check 5 | PASS | 24s |
| 8. Storage targets: S3 (Garage), local path, mounted directory | PASS | 19s |
| 9. Image scan (Trivy) and dependency audit (pnpm audit) | PASS | 18s |
| 10. Endpoint backup: the agent enrolls, backs up a folder, restores it | PASS | 11s |
| 11. Mail import (folder and upload) and export (EML ZIP, MBOX), compared by hash | PASS | 8s |
| 12. File share backup against Samba: back up, browse, ZIP, restore with permissions, copy job | PASS | 2m 19s |
11 of 12 checks passed in full, 0 partly, 1 skipped, 0 failed. The full report, including the reason for every skipped or partial check, is attached to the release as smoke-report.md.
The Community images were smoke-tested on their own (smoke-report-community.md, smoke-report-community-arm64.md): amd64 PASS with gaps: 9 of 12 checks passed in full, 0 partly, 3 skipped (see the reasons below); arm64 PASS with gaps: 9 of 12 checks passed in full, 0 partly, 3 skipped (see the reasons below).
Release-Notes von 0.4.1 auf GitHub ↗
0.4.0 beta · 16. Oktober 2026
Die Release-Notes dieser Version gibt es nur auf Englisch.
Restow 0.4.0 backs up SMB and NFS file shares from the server, without an agent on the
file server, and restores them with their permissions. It adds a notification matrix per
channel and event, shows the progress of running Proxmox VE backups, lets an update wait
for or cleanly stop the backups in progress, and moves the database to another disk from
the web interface. It adds immutable backups (S3 Object Lock per repository, a deletion
delay for directories), ransomware detection on every new restore point with a retention
hold while a finding is unresolved, boot tests and file restore (Preview) of Proxmox VE VM
restore points, backup and restore of SharePoint Online sites, agent policies, and file
restore for the restore role. S3 endpoints saved from now on must use HTTPS. Seventeen
database migrations run at start; file share backup and the database move need the 0.4.0
docker-compose.yml (run the 0.4.0 installer again after the update, see Upgrade Notes).
SharePoint needs an added permission and a new admin consent per tenant.
Breaking changes
Nothing stops working on update: existing compose files, webhooks, notification recipients, API clients and agents keep working as before. What behaves differently:
- Notifications follow the matrix. Every channel (the bell, each webhook, each
notification recipient) now keeps the events it gets, and an alert rule no longer sends
an event to a channel whose column has it off. Migration 0038 fills every column with
exactly what the channel received before, so nothing changes on update. Afterwards:
- The webhook dialog no longer has an event picker. Choose a webhook's events under Integrations › Notifications.
- A webhook created after the update (in the interface, or through the API without
events) starts with the defaults of its format: a Discord, Slack or Teams webhook gets errors and warnings, a signed JSON (restow) webhook everything. A rule that sends other events to it delivers them only once they are switched on in the matrix. - The webhook stream keeps its event names (
job.failed,job.completed,verify.completed) and payloads.backup.succeededis the matrix's name for what the stream callsjob.completed(an alias, not a rename); a webhook subscribed tojob.completedkeeps getting it.eventson create and update still means the subscribed stream events; the session API also returns the webhook's column asnotifyEvents. - The four flags of a tenant's notification recipients (
notify_job_failures,notify_weekly_report,notify_readiness_red,notify_license_updates) are replaced by an event list. The tenant API still accepts and returnscategories; a recipient now also carriesevents. "Licence and update notices" never sent anything and is no longer returned. Only scripts that read these columns from the database directly need a change.
- New installations start the mounter.
install.shnow starts the mounter (compose profilemounts, it holds the Docker socket) by default, because file share backup runs through it. Scripted installations that do not want it pass--no-mounter(or--without-mounter). Running the installer again on an existing installation keeps that installation's choice. - Installer guard. Once the database was moved to another disk,
install.shrefuses (exit code 8, nothing changed) to put in place or start adocker-compose.ymlthat does not readRESTOW_POSTGRES_DATAfrom.env, so an older release file cannot start the stack without its database. - Building from source needs Node.js 22.12 or newer (
enginesinpackage.json; commander 15 requires it). The Docker images run onnode:22-slimas before; nothing changes for Docker installations.
Added
Unless marked otherwise, everything below is part of every edition (the Community core).
File shares (SMB and NFS)
- File share backup, in the menu next to VMs & containers. Restow mounts an SMB share
(Windows Server, Samba, a NAS) or an NFS export read-only for the length of one run, in
a short-lived runner container started by the mounter, and backs it up with restic into
a repository of its own (
file-shares/<share id>/on the tenant's primary repository). No agent on the file server, and the api and the worker are never restarted. NTFS permissions (and NFSv4 or POSIX ACLs, best effort) are kept in each restore point. Open, unreadable and offline files are skipped and listed in the run, which then ends "with warnings". SMB 2.1 to 3.1.1; SMB1 and NTLMv1 are refused. Requirements (the mounter, thecifsmodule or the NFS client on the Docker host, the ports, the account) are in docs/FILESHARES.md. - Add file share tests the connection and whether permissions are readable; the password is sealed with the tenant key and never shown again. Backup jobs of the kind File shares: schedule (at most hourly), folders, file types to skip, retention (daily, weekly, monthly). Tenant admins manage their own shares; a share on a private or loopback address needs a provider admin's approval or the installation switch Tenants may use private networks.
- Restore from a restore point (browse, search, versions): download as ZIP, restore to a new folder, to the original location (overwrite, keep both, skip) or into another share, with permissions where the target allows it. Restores into a share need Allow restore to this share on it (off by default).
- Restore checks: every new restore point is checked by reading up to 20 sampled
files back and comparing them, and the repository gets a weekly
restic checkof 5 % of its data; Recovery readiness rates a share by its newest restore point. A restore check of a restore point without samples (every file changed in the hour before the run) rates yellow and says why. - Copy jobs: on a schedule, the newest restore point of share A that passed its restore
check is written into a folder of share B, in mode
overwriteormirror(mirror deletes only inside that folder; refused into a share root or the source share, and stopped when the restore point has fewer than half the files of the last copy). A copy job keeps no versions and is labelled as not being a backup. - Budgets per share, per tenant and as a default (off by default; provider admins): a warning at 80 %, no new backups at 100 %.
- File shares count in the status tab, the start page, Recovery readiness, warnings,
History, the statistics and the provider view, with the alerts
file_share_backup_failedandfile_shares_without_job. - Enable network shares (Installation › Default repository & network shares, and the notice on the File shares pages) starts the mounter of an existing installation through the opt-in updater, for the provider owner, with a recent sign-in and an audit entry. File share runners, on the same page, sets how many runs go at a time and the memory per run.
Immutable backups
- Immutability per repository, on each repository's card (Repositories › Change
immutability), off until an administrator turns it on. What is locked: packs,
committed manifests and wrapped keys of the chunk store (Microsoft 365, IMAP, Proxmox VE
disks) and the
data/,snapshots/,keys/andconfigobjects of every restic repository (machines, file shares, Proxmox VE containers). Not locked: checkpoints, staging, exports, downloads, resticlocks/andindex/files (restic repair indexrebuilds the index from the locked packs). See docs/STORAGE.md, "Immutable backups". - S3 Object Lock (
complianceorgovernance, 1 to 3650 days): turning it on checks the bucket's Object Lock configuration and refuses a bucket without it. Every locked object is written with a retain-until date of the period plus 7 days; the daily retention job renews the lock of every object still in use once the last complete renewal is 6 days old, so data that new restore points reuse stays locked for at least the period. A renewal that was interrupted continues where it stopped. Retention, garbage collection and restic prune treat a deletion the storage refuses as "not yet": the restore point stays visible and restorable, and space comes back once the lock has run out (up to the period plus 7 days later). Restow never sends the governance bypass header. - Deletion delay for directories (the Docker volume, an NFS share): Restow's own code refuses to delete or overwrite a locked file until the period has passed since it was written. It protects against misuse of Restow (a stolen administrator account, a retention policy shortened to delete restore points), not against someone with access to the server or the share, and the interface says that it is not immutability.
- Verification: the daily retention job and Verify now ask the storage for the
retention of a sample of recent objects; objects without a lock or in a weaker mode, a
renewal that is overdue or failed and deletions waiting for their lock are shown on the
repository card, the dashboard's storage tile and, as
immutability_warning, in the provider view. Restore points of the restore explorer and of a machine show "Immutable until ", green only for a COMPLIANCE retention the storage itself reported. - Who may change it: raising the protection is open to whoever may configure the
repository; lowering it (fewer days, a weaker mode, off) is for the provider owner with a
sign-in from the last ten minutes and applies only to data written from then on. Every
change and verification is audited (
storage.target.immutability_changed). - What it protects against: an attacker on the Restow server, someone holding Restow's
storage key, a stolen administrator account, a shortened retention policy. What not:
someone who controls Restow can stop new locks and the renewal (what is locked stays
locked until its date); a GOVERNANCE lock is lifted by any account with
s3:BypassGovernanceRetention; delete markers and newer versions can hide locked data (the locked versions stay and can be brought back); the master key is not in the bucket.
Ransomware detection
- Every new restore point is judged for signs of ransomware from data the backup already has, every two minutes, for runs of the last 72 hours: the amount of change (new and changed files, bytes added) against the object's own history, mass deletions, renamed extensions, known ransomware extensions and ransom notes (versioned lists, matched on the server), the entropy of sampled new files, and the compression and deduplication ratio of the run's new data. The signals apply per kind of object: machines, file shares, Proxmox VE containers and VMs, mailboxes, OneDrives, SharePoint sites and IMAP accounts (deletions, renames, names and entropy exist only for machines, file shares and OneDrives). A signal without data says "not available", never clean. It never reads the data a second time, never blocks a backup and is no virus scanner. See docs/RANSOMWARE.md.
- Suspicious badge (red) on the restore point and the object in every restore view; when the newest restore point is suspicious, the restore views offer the newest one without findings. A click shows each finding with its numbers and the state of every signal.
- False alarm: technicians and administrators mark a finding as a false alarm with a
note, or take it back (audited,
suspicion.false_alarm,suspicion.false_alarm_revoked); the restore point then counts as clean and joins the baseline. - Retention hold: while an object has a suspicious restore point nobody resolved,
retention,
restic forgetand prune delete no restore point of that object, so clean older restore points are not pruned while encrypted ones pile up. Backups go on and quotas still apply. Only an administrator ends a hold, never a later clean restore point: Mark as false alarm, or Release hold (administrators, recent sign-in, auditedsuspicion.hold_released). The object shows "Retention paused" until then. - Notifications:
backup.suspicious(error, once per attack episode, says that retention is paused) andbackup.suspicious_hold(warning, when a hold is still open after 14 days and every 14 days after), in the bell, the rules and the webhooks. - Installation › Ransomware detection: the thresholds of every signal, each signal's
switch, the retention hold's switch and its reminder days (
settings.ransomware.updated; the provider owner changes them, every provider admin reads them). - The activity report (deletions, renames, names, entropy) needs the endpoint agent 0.4.0 on machines; the compression signal needs the agent 0.4.0 on machines and restow-pve 0.4.0 for containers. File shares get it with the 0.4.0 runner, VMs and Microsoft 365 objects with the server.
Notifications
- Notification matrix under Integrations › Notifications (#76): the events as rows,
grouped and marked by severity; the bell, every webhook and every notification recipient
as columns, each with the quick choices "Errors only", "Errors and warnings" and "All".
Saving is written to the audit log (
report.matrix_updated). Installation events (an update is available, low disk space) are rows for provider admins only. - New events
backup.succeededandverify.completedfor mail and the bell (off in the bell by default), andinstallation.disk_low(see Updates and the database).
Proxmox VE
- Progress of a running backup (#51): VMs & containers, the inventory and the guest's page show a progress bar ("34% · 3.2 GB of 9.4 GB · 85 MB/s"). Needs restow-pve 0.4.0 on the node; a backup of an older helper shows "No progress reported yet".
- The helper's own lines in the run's log (#61): the run id, what restic added, what it could not read and the commit of the restore point now reach the log Restow keeps for the run. A backup that succeeded with gaps names the items restic could not read (the first 20).
- Proxmox VE jobs in Servers & clients › Jobs (#53), next to the machine jobs with a Type column: guests per job, schedule, last and next run, "2 of 5 guests done" while a round runs, and a backup started by hand as a row "Manual backup · " until it ends. New job is a menu with one entry per type; the Proxmox VE job form lists the VMs and containers to put into the job.
- Create recommended job (#52) next to every "no job" notice (jobs, inventory, sources, directory, VMs & containers) and "Protect everything without a job" on the dashboard's readiness card: a preview of what the click creates or adds to, then one job per kind (mail every 8 hours; machines per system and profile; one Proxmox VE job, daily at 22:00 in snapshot mode). A second click adds to the same job instead of making another. Admins only; recorded in the audit log.
- Files of a container in Servers & clients › File restore (#62): every container with a restore point is listed in the group "Proxmox VE containers"; browse a restore point and download files and folders as one ZIP, read by the server from the container's repository. The guest page links each container restore point there (Browse files). Reads and downloads are in the audit log.
- Files of a VM in Servers & clients › File restore (Preview): VMs with a restore
point are listed in their own group "Proxmox VE VMs", marked Preview, and the guest
page links them (Browse files). Each readable file system of the VM's disks is a
folder (
scsi0-p2,vg0-root): partitions of GPT and MBR disks and linear LVM logical volumes with ext2, ext3, ext4 (the journal replayed in memory), XFS, NTFS or FAT12/16/32. Browse and download files and folders as one ZIP; files that cannot be read are named in_not-restored.txtinside it. The server reads the disks from the tenant's chunk store with its own user-space readers in a short-lived, restricted child process; nothing is mounted, on the server or on the node. Not readable: btrfs, ZFS, ReFS, LVM thin, RAID, BitLocker and LUKS, NTFS-compressed and EFS files; the XFS log and NTFS's$LogFileare not replayed. Same routes, roles and audit actions as for containers (withkind: "vm"). The volume list asks to compare an important restored file with the original before relying on it. See docs/PVE.md, "Files of a VM". - Boot tests of restore points: a Proxmox VE job can boot the newest restore point of
each guest weekly or after every backup (off by default; a memory limit, default 8 GiB,
and a wait for the guest agent, default five minutes), and Boot test now on a restore
point asks for one by hand. The guest's node restores it as a new guest in the pool
restow-restore, isolates it before the start (every NIClink_down=1or an isolated bridge, passthrough devices, serial ports, bind mounts and the hook script removed), starts it, waits for the QEMU guest agent (a container: its init) and destroys it in every case; leftovers are removed when the service starts. One test per node at a time, never beside a backup, and only with enough memory and storage. Green when the guest agent answered, yellow when the VM only started, red when the restore, the start or the boot failed. Readiness rates the newest restore point by its boot test where there is one. New eventsboot_test.failedandboot_test.unproven. Needs restow-pve 0.4.0 on the node (restow-pve config --boot-tests,--boot-test-storage,--boot-test-bridge); the guest's page says when its node cannot. Requesting one is audited (pve.boot_test.requested). See docs/PVE.md, "Boot test". - A guest shows the average a follow-up backup adds (over the newest 10 restore points after the first backup) (#58).
Servers and clients
- Data folders a job misses (#59): the endpoint agent 0.4.0 reports which of a fixed
list of Linux data folders (
/opt,/usr/local,/srv,/var/www, Docker and Podman volumes, the PostgreSQL, MySQL and MongoDB folders under/var/lib) exist and hold files, names only. The job editor names the folders the job's machines really have and leaves out, and a machine's page offers Add this folder to the job. With older agents the notice of 0.3.5 stays. - A machine's page says what it runs as (container, virtual machine, physical, with or without a desktop) (#59).
- The file browser of a restore point says which folders it contains, with a link to the job's folders (#59). A machine's restore points say what they contain and what they added, like Proxmox VE guests (#58).
- Agent policies for servers and clients, on three levels: the installation
(Installation › Agent policy), the tenant (tenant page › Agents) and the backup job (the
job editor). Each level may override a setting unless the installation locks it; every
view says where a value comes from and whether it is locked. The settings: a backup
window (weekdays and a time range, also across midnight, in the zone of the job's
schedule) in which scheduled backups, catch-ups and retries may start (a running backup
continues, Back up now ignores it); catch up missed backups as soon as the
machine is on again or in the next backup window, optionally only up to a maximum age;
the upload limit of a job without its own (a job can also choose Unlimited,
which sets a policy's limit aside unless the installation locks it; a job whose limit is
empty keeps inheriting); only on AC power; and the number of automatic retries
(0 to 10). Without a policy agents behave exactly as before. The server writes the
effective policy into each machine's configuration (a new configuration version) and
audits every change (
settings.agent_policy.updated,tenant.agent_policy.updated,endpoint.config.changed). The page of a server or client shows the policy that applies to it, each setting with its source (default, installation, tenant, backup job or the machine itself) and whether it is locked, read-only (restore operators see it too), and why a due backup waits next to the next planned start: for the backup window, for an update to finish, for AC power, or to catch up in the next window. The agent 0.4.0 sends that reason with its heartbeat (waiting); for an older agent the page shows none. Window, catch-up, retries and the waiting reason need the agent 0.4.0; the upload limit and AC power reach older agents too. - Agents respect the update pause (#46): while an update pauses new runs, the agent
0.4.0 starts no scheduled backup, retry or catch-up and waits for the pause to end (the
configuration and the heartbeat say
startsPaused); the wait does not count as a missed or failed backup. A Back up now request stays queued on the server until the pause is over, also for older agents, andrestow-agent backup-nowon the machine waits with a message.restow-agent statusshows the policy and why a due backup waits. - File restore for the restore role: restore operators (membership role "restore",
tenant_restore) now open Servers & clients › File restore. They list the machines, read a machine's restore points and their immutability, browse them, download files as a ZIP and restore files onto the machine; for Proxmox VE they read the overview and a guest's restore points and browse and download files of container and VM restore points. Settings, tokens, jobs, backing up, verify and boot tests, restoring a whole guest, revoking or deleting and the repository password stay with the administrators (backing up answers 403), and the web app leaves out the links to pages they may not open. Every read, download and restore is audited with the operator as actor.
Jobs, live view and dashboard
- Running backups in the sidebar (#57): the Jobs entries and VMs & containers show a spinner with the number of running backups and the waiting ones beside it; the tooltip lists them, a click opens the run.
- Live run drawer (#54): the charts move with time between measurements, the numbers count up, the time left counts down, and a line says when the run last reported (or that Microsoft Graph throttles it). The browser tab's title shows the percent while the drawer is open.
- All tenants in Jobs (#63, Service Provider): under "All tenants", Jobs of Mail & SaaS and of Servers & clients list every tenant with its jobs per kind, what runs and waits, how the newest backups ended and the next run, with filters and sorting; a row opens the tenant's jobs read-only.
- Storage growth on the dashboard (#64): 1 week, 1 month, 3 months or 1 year, from 3 months on with the estimate as a band between the slowest and fastest growth, and when the repository runs full at this growth where its free space is known.
Microsoft 365
- The first backup of a large mailbox shows "First backup: X of Y items" over all attempts, with an estimated time left (#47). A OneDrive shows "X items so far" until it is fully listed.
- SharePoint Online sites: every directory sync finds the tenant's sites
(
/sites/getAllSites; sites of Microsoft 365 groups and Teams included, personal sites left to their owner's OneDrive), and each site is a protected object of its own, in the mail jobs like mailboxes and OneDrives. The protection rules have a sites mode: all sites (the default) or only the selected ones. A backup holds every document library (with the OneDrive engine: delta per library, optional versions, checkpoints), every list with its columns and each list item's field values as JSON, and the site's description; a library or list Graph refuses is reported and keeps its last copy. New sites get their first backup at once; a deleted site fails withgraph.site_unavailable. - Restore of SharePoint sites in the explorer (libraries, folders, files, lists, items): download as ZIP; files and folders into the original library or another library of a backed-up site of the same source ("Keep both", "Overwrite" with SharePoint keeping the old file as a version, "Skip existing"); list items into their original list as new items, writable fields only. Restore checks sample library files like a OneDrive. Sites appear in the status, count as no protected mailbox, and are seen by restore operators and administrators only. Not backed up: Teams chats, attachments of list items, site design, navigation and workflows; permissions are kept as information and never restored. See docs/MICROSOFT.md, "SharePoint Online".
Updates and the database
- Runs in progress during an update (#46): the install dialog counts what runs and waits in every tenant and asks: Stop them cleanly (the default: Microsoft 365 and mail runs save a checkpoint and stop, runs on agents and of file shares are waited for, 30 minutes at most), Wait until they finish (two hours at most) or Do not wait (as before). From the confirmation until the update is over no new run starts; schedules that fall due meanwhile run afterwards. Everyone signed in sees a banner; the Updates tab shows what still runs, Start now and Cancel.
- Installation › Database (#73): where the database keeps its data, its size, the free space under it and under the local default repository, and what the next update needs. With the opt-in updater, the provider owner moves the database to a directory on another disk: checked first (another local file system, ext4, XFS, Btrfs or ZFS, room for the data), then copied, compared file by file, test-started and switched, with automatic rollback on any failure. The old copy is kept and blocked from starting until it is removed. See docs/DATABASE.md.
- Low disk space warning (#73): every 15 minutes the api checks the disk under the database (through the updater) and under the local default repository; below a tenth free, and always below 5 GiB, the provider admins get a notice in the bell, and rules that list "Low disk space" send it, once per episode.
- Kept database dumps (#73): the Updates tab lists the updater's pre-update dumps; the provider owner can download one (one-time link, recent sign-in, audit log) or delete it.
API
- Integration API contract 1.4.0 (additive):
GET /api/v1/statushasfileShares(counts of file shares) and the readiness summarysharesWithoutJob, andeventsis optional when a webhook is created. Nothing was removed or renamed.
Changed
- Updates: the updater's preflight now adds up what an update writes (the dump, the
images, room for the migrations, plus
RESTOW_UPDATER_MIN_FREE_MBas a margin) and refuses an update that does not fit (blockerdisk_space, with the numbers), instead of requiring a fixed 1 GB (#73). - A Linux machine enrolled with a client token whose agent (0.4.0) reports a container or a virtual machine without a desktop gets the server profile, because it runs services; the machine's page says why (#59). Existing machines keep their profile.
- Adding a folder to a machine job narrows an exclusion of a parent folder: adding
Docker's volumes turns
/var/lib/dockerinto/var/lib/docker/*and!/var/lib/docker/volumes(#59). - Notification recipients: the categories in the tenant wizard and on the tenant page add or remove their events and leave everything else chosen in the matrix alone.
- The live channel stays open while the tab is in the background (closed after ten minutes, or when the browser freezes the tab), so a page no longer reloads when you come back (#54).
- Mailboxes and OneDrives are named by their person (display name, else address), not by their technical id, which moves to a tooltip (#55).
- The sidebar's Installation section folds away to its header; the choice is remembered in the browser (#56).
- A machine's danger zone reads "Stop backing up this machine" and says that nothing is deleted; revoked machines are hidden in the inventory until "Show revoked machines" and have their own group in File restore (#65).
- The machine job editor says that Proxmox VE VMs and containers are backed up by Proxmox VE jobs, with links (#53).
- Proxmox VE: sizes are named ("9 GB allocated"); "Waiting for the node" says since when, and turns amber while the node is disconnected.
- Container backups on Proxmox VE (restow-pve 0.4.0) let restic scan before it backs up
(no more
--no-scan), so there is a total to show progress against. - docs/ARCHIVE.md explains what journaling captures and misses compared with the mailbox backup, and when to use which (#48).
- Dependencies: major updates of the build and test tooling and of two libraries: vite 8, @vitejs/plugin-react 6, vitest 5, lucide-react 1.x, commander 15, archiver 8, @biomejs/biome 2.5.
- Performance on large installations: the "All tenants" view of Jobs looks up each object's newest backup through an index, reads four tenants at a time and keeps each tenant's figures for 30 seconds for every viewer (the page refreshes every 15 seconds while something runs, else every minute); the sidebar's Proxmox VE badge asks a slim endpoint instead of the whole VMs and containers overview; the ransomware judgement reads new restore points through partial indexes, judges batch after batch for up to a minute per pass and logs restore points that leave its 72-hour window unjudged; the reconciler of left-behind jobs runs in one worker at a time; a heartbeat no longer rewrites the machine's settings when its facts did not change.
- The file share search needs at least three characters of the name.
- Performance with the largest workloads; memory now stays bounded whatever the size:
- File share catalog: the first catalog of a share (or one after a gap) streams
restic lsinto the database in batches of 5,000 instead of holding every file in memory and writing it in one transaction. An interrupted pass stays pending and continues without duplicates. - SMB file share runner: the permission reuse streams the previous sidecar into a
compact index (about 50 bytes per file instead of about 190), so incremental runs of
shares with millions of files no longer run out of memory. Above a third of the
runner's memory limit the run reads all permissions instead
(
RESTOW_SHARE_REUSE_MAX_ENTRIESoverrides the limit). - SharePoint: a site run indexes the previous restore point once instead of scanning it for every list and library, so sites with thousands of lists and a million items no longer take quadratic time.
- Proxmox VE: the block maps of VM disks being browsed or restored are cached by size
(256 MiB by default,
PVE_BLOCK_MAP_CACHE_MB) instead of by count. - Object Lock renewal sends 32 requests at a time instead of 8
(
IMMUTABILITY_RENEWAL_CONCURRENCY) and continues an interrupted pass where it stopped instead of starting over.
- File share catalog: the first catalog of a share (or one after a gap) streams
Fixed
- A Proxmox VE backup running while Restow was updated failed: the node helper gave up after about 30 seconds, while an update restarts the api and runs migrations. The node (restow-pve 0.4.0) now keeps trying for five minutes (#46).
- A Proxmox VE backup run whose end never reached the server stayed "running" for 48 hours. It is now closed once the node (restow-pve 0.4.0) no longer lists it in its heartbeat (#46).
- restow-pve's own lines never reached the run's log in Restow: vzdump writes a backup provider's lines to the PVE task log only, not to the guest's log file (#61).
- Jobs of a worker that was killed (not stopped) stayed "running" until they expired, 23 hours for a backup, because nothing gave them back. The next worker now returns them to the queue two minutes after its start (#46).
- A job stopped by a restart or an update before its first checkpoint used up one of its attempts, and on its last attempt the explanation said it would continue although its checkpoint was discarded (#46).
- An update could fill the disk with its database dump and stop PostgreSQL midway, because the preflight only checked for 1 GB free (#73).
- Adding
/var/libto a machine job, as the 0.3.5 notice offered, still left Docker's named volumes out, because the default exclusion/var/lib/dockercovers them (#59). - The live run drawer's charts shrank to the last 80 seconds and grew back every ten seconds, because each live event replaced the run's measurements instead of adding to them (#54).
- Notification mail through the backup's app registration from a tenant that never consented to it reported "app not found" and asked to check IDs that were right. It now says that consent is missing in the sender's tenant and links the admin consent.
- The update dialog's confirm button was enabled while the runs in progress were still being read, so a quick click announced the update before the admin saw them. It now stays disabled until they were read (or reading them failed).
Security
No vulnerability was fixed. Security-relevant changes:
- Database dumps can be downloaded from the Updates tab. A dump holds the whole database, the encrypted secrets included: provider owner only, with a recent sign-in, through a one-time link, recorded in the audit log. Keep a downloaded dump as carefully as the master key.
- New installations start the mounter by default, which mounts the Docker socket (root on
the host); read docs/MOUNTS.md, or install with
--no-mounter. File share runners have no network but an internal one to the api, and write with a credential that is valid for one run and append-only. - Tenant admins can add file shares themselves; shares on private or loopback addresses need a provider admin's approval or the installation switch.
- Browsing and downloading files of a Proxmox VE container are recorded in the audit log
(
pve.snapshot.browsed,pve.snapshot.downloaded); a prepared download can be started once, within ten minutes, by the admin who prepared it. The same holds for files of a VM (kind: "vm"), which a reader in a restricted child process reads without mounting anything (threat model in docs/PVE.md). - S3 endpoints need HTTPS. A new or changed S3 endpoint over plain
http://is refused (endpoint_insecure), for provider admins and the installation default too, except tolocalhost,127.0.0.1and[::1]. Endpoints saved before andS3_ENDPOINTkeep working; their card, Installation › Default repository and every test say in red that they should move to HTTPS.S3_ALLOW_INSECURE=trueaccepts plain HTTP for test and development setups only. - Restore operators can now browse, download and restore files of machines and of Proxmox VE guests (see Servers and clients); every read, download and restore is audited.
- Lowering a repository's immutability and releasing a retention hold need a recent sign-in and are audited; lowering is for the provider owner only.
Upgrade notes
New image, seventeen database migrations (0035 to 0051), and a new docker-compose.yml for
file shares and the database move.
- Update as usual (the opt-in updater, or
docker compose pull && docker compose up -d). The api applies the migrations as it starts. With the updater, the install dialog now asks what to do with runs in progress; the default stops them cleanly. - Run the 0.4.0
install.shagain in the installation directory (README.md). It replacesdocker-compose.ymlwith the 0.4.0 file (checked against the signed SHA256SUMS), keeps the previous one asdocker-compose.yml.bak-<timestamp>and leaves.envas it is. Without it everything else works, but file share runs cannot start (the mounter reportsrunner_network_missing) and Installation › Database cannot move the database. A compose file kept by hand needs the changes of the release file: the database volume read from.env, the internalrunnersnetwork on the api, andRESTOW_MOUNTER_URL, the runner limits and therestow-mounter-sharedvolume on the worker. - For file shares, start the mounter if it is not running: Enable network shares in
the web interface (with the opt-in updater) or
docker compose --profile mounts up -d mounter. The Docker host needs thecifsmodule for SMB and the NFS client for NFS. - Proxmox VE nodes: restow-pve 0.4.0 updates itself (it checks every six hours and updates
while idle), or run
restow-pve updateon the node. Older helpers keep working without progress, without the five-minute retry window and without the list of active runs. - Servers and clients: the endpoint agent 0.4.0 updates itself unless the tenant paused agent updates. Older agents keep working without data folders, machine facts, the backup window, catch-up rules and retry count of an agent policy, and do not hold their own schedules during an update pause.
- Plain-HTTP S3 endpoints: a repository or default repository that uses
http://to a host other than the machine itself keeps working, but its card asks in red to move it to HTTPS, and changing its location needshttps://(docs/UPDATING.md). Test setups with an object store on the compose network setS3_ALLOW_INSECURE=truein.env(api and worker). - SharePoint Online: the backup's app registration needs the application permission
Sites.ReadWrite.All(Sites.Read.Allis enough to back up, not to restore). Add it to the app registration, then the customer's admin opens the source's consent link again (docs/ENTRA-SETUP.md). Until then mail and OneDrive keep working, and the directory sync warns that sites are neither found nor backed up (sites_unavailable). - Immutable backups with S3 Object Lock need a bucket created with Object Lock (and
versioning); it cannot be added to an existing bucket. The access key needs
s3:GetBucketObjectLockConfiguration,s3:PutObjectRetention,s3:GetObjectRetention,s3:ListBucketVersionsands3:DeleteObjectVersion, and should not haves3:BypassGovernanceRetention,s3:PutBucketObjectLockConfigurationors3:PutBucketVersioning. Nothing is locked until an administrator turns it on. - Ransomware detection is on after the update and judges backups of the last 72 hours; its retention hold is on as well, so a suspicious restore point pauses retention of its object until an administrator resolves it. Thresholds and both switches are under Installation › Ransomware detection.
- Database migrations, in this order:
0035_file_shares,0036_backup_job_kinds_share_copy,0037_backup_job_file_shares(file shares),0038_notification_matrix(it translates the recipient flags and webhook event lists of every tenant and drops the four flag columns),0039_pve_run_progress,0040_recommended_jobs,0041_pve_downloads(container downloads),0042_job_start_pause(the update pause),0043_disk_alerts(the disk warning state),0044_pve_boot_tests,0045_ransomware_detection,0046_sharepoint_sites,0047_immutable_backups,0048_suspicion_retention_hold(the release of a retention hold and its reminders, five columns onrestore_point_suspicions),0049_perf_indexes0050_agent_policies(the installation's and each tenant's agent policy,settings.agent_policyandtenants.agent_policy, both{}, which changes no machine's configuration) and0051_agent_waiting(endpoints.agent_waiting, what a due backup waits for as the agent reports it; empty until an agent 0.4.0 reports). They change the schema and backfill only the notification recipients and webhooks, a few rows per tenant, so they should take seconds on any installation, except0049_perf_indexesbelow. They ran on a 0.3.6 schema in the Postgres test suites; they were not timed on a production-size database. 0049_perf_indexesadds six partial indexes (jobs,endpoint_runs,file_share_runs,pve_runs,pve_tasks). Each build reads its table once while writes to it wait (the migrator cannot build them concurrently): seconds on most installations, about a minute per ten million rows on large ones (docs/UPDATING.md).- 0035 creates the
pg_trgmextension for the file share search when the database role may; an external PostgreSQL without it searches more slowly, with the same results. - New optional environment variables:
RESTOW_POSTGRES_DATA_TYPEandRESTOW_POSTGRES_DATA(where the database lives; empty means the volumepgdata; the updater writes them when it moves the database),RESTOW_MOUNTER_MAX_RUNNERS(hard cap of file share runners, default 8) andRESTOW_MOUNTER_RUNNER_MAX_MEMORY_MIB(default 16384). No new required variables. - Downtime: the containers restart and the migrations run, as for 0.3.6.
- Rollback: the migrations are not reversible; go back to 0.3.6 only with the database dump
taken before the update. After a database move, keep a compose file that reads
RESTOW_POSTGRES_DATA: the 0.3.6 file does not, and PostgreSQL then refuses to start on the old copy.
Known issues
- Not tested against real systems before the tag: a Proxmox VE node (progress, the helper's log lines, the five-minute retry window and the closing of dropped runs were tested against the simulated node of the test suites), the database move and the Enable network shares button through a real updater and its Docker helper container, and the new pages in a browser by hand (they are covered by component tests).
- File shares were tested against Samba in the release smoke tooling, not against Windows Server (NTFS permissions, Backup Operators, a file kept open in Excel), a Synology or TrueNAS share, real NFS exports (NFS is not in the smoke check) or a host with SELinux enforcing.
- File shares have no VSS over SMB (files open with an exclusive lock are skipped), no alternate data streams, DFS namespaces, Kerberos or SMB1; repositories live on the primary repository only; tenant users have no self-service restore of shares; scheduled reports have no file share block yet.
- While an update waits or runs, agents older than 0.4.0 do not hold their own schedules: a backup such a machine starts by itself during that time runs, and may fail if the api restarts under it.
- Files of Proxmox VE containers and VMs are downloaded as a ZIP; restoring single files into the running guest is not built. VM file restore is a Preview: btrfs, ZFS, ReFS, LVM thin, RAID, BitLocker and LUKS are not readable, and the XFS and NTFS logs are not replayed, so a crash-consistent restore point can lack the last writes; compare an important file with the original before relying on it.
- Immutable backups, SharePoint Online, boot tests, VM file restore and agent policies were tested against simulated services only (a fake S3 with Object Lock, a simulated Microsoft Graph, a simulated Proxmox VE node), not yet against a real S3 service with Object Lock, a real Microsoft 365 tenant or a real Proxmox VE cluster. The ransomware signals were tested with simulated attacks, not with live ransomware.
- Immutable backups: the installation default repository cannot be made immutable (give the tenant a repository of its own or an immutable copy); restic index files are not locked; a tenant whose retention schedule was deleted is not renewed; space of deleted data comes back only once its lock has run out; a file share whose repository is still locked cannot be purged before then.
- SharePoint: attachments of list items, site design, navigation, workflows and permissions are not restored; a deleted site or library is not recreated; list items go back only into their original list.
- In "This restore point contains", Windows paths are listed but do not open.
- Deleting a revoked machine together with its restore points is not possible yet.
- The known issues of 0.3.6 still apply.
Verification
Before the tag, on 2026-10-15, on the release branch (main plus the 0.4.0 branches): lint and typecheck of all workspaces, the build, every unit suite, the Postgres suites on Postgres 16 (129 test files, 1505 tests), the Go agent tests, the Perl plugin tests of the Proxmox VE integration, the server installer tests (679) and the CI and smoke tooling tests (241). Smoke check 12 (file shares: back up, browse, search, ZIP download, restore with permissions, copy job against Samba) passed in CI on the 040-fileshares branch (run 38668096804). The release smoke runs in the release pipeline; no Microsoft 365 tenant was used before the tag.
Release pipeline, 2026-10-16:
| Check | Result | Duration |
|---|---|---|
| 1. Install: images, compose up, migrations (new install and upgrade) | PASS | 94s |
| 2. Health endpoints, worker and scheduler registered | PASS | 0s |
| 3. Passkey sign-in E2E with a virtual authenticator, tenant creation, i18n de/en | PASS | 2m 08s |
| 4. Microsoft 365 backup and restore against the dev tenant | SKIPPED | 0s |
| 5. IMAP backup and restore against Dovecot, hash comparison | PASS | 8s |
| 6. Journal receipt, chain verification, export | PASS | 3s |
| 7. Standalone restore with restow-restore from the storage of check 5 | PASS | 24s |
| 8. Storage targets: S3 (Garage), local path, mounted directory | PASS | 22s |
| 9. Image scan (Trivy) and dependency audit (pnpm audit) | PASS | 19s |
| 10. Endpoint backup: the agent enrolls, backs up a folder, restores it | PASS | 12s |
| 11. Mail import (folder and upload) and export (EML ZIP, MBOX), compared by hash | PASS | 8s |
| 12. File share backup against Samba: back up, browse, ZIP, restore with permissions, copy job | PASS | 2m 15s |
11 of 12 checks passed in full, 0 partly, 1 skipped, 0 failed. The full report, including the reason for every skipped or partial check, is attached to the release as smoke-report.md.
The Community images were smoke-tested on their own (smoke-report-community.md, smoke-report-community-arm64.md): amd64 PASS with gaps: 9 of 12 checks passed in full, 0 partly, 3 skipped (see the reasons below); arm64 PASS with gaps: 9 of 12 checks passed in full, 0 partly, 3 skipped (see the reasons below).
Release-Notes von 0.4.0 auf GitHub ↗
0.3.6 beta · 15. Oktober 2026
Lässt Sie Proxmox-VE-Gäste direkt im Inventar schützen, gibt den Platz des alten Backup-Index ohne Neustart der API zurück, zeigt einen Hinweis mit einer Schaltfläche, wenn ein Dienst einen Neustart braucht, und aktualisiert die Compose-Datei älterer Installationen, wenn der Installer erneut läuft. Eine Datenbankmigration.
Neu
- Proxmox VE: Gäste direkt im Inventar schützen: Unter Server & Clients, Inventar hat jede VM und jeder Container seinen Backup-Job als Auswahl (ein vorhandener Job, „Kein Backup-Job“ oder „Neuer Job …“) und „Jetzt sichern“. Gäste lassen sich einzeln ankreuzen, alle eines Knotens oder alle ohne Job mit einem Klick, und dann einem Job hinzufügen („Zu Job hinzufügen …“) oder gemeinsam sichern; „Neuer Job …“ öffnet den Job-Dialog und legt die Auswahl in den neuen Job. Die Schutzspalte des Inventars heißt jetzt „Schutz“. Proxmox VE bleibt eine Preview. (Jede Edition)
- Hinweis „Neustart erforderlich“ mit „Jetzt neu starten“: Braucht ein Dienst einen Neustart, zeigt Installation, Updates den Hinweis „Neustart erforderlich“ mit dem Grund, der Schaltfläche „Jetzt neu starten“ und dem Befehl zum Kopieren, im Verzeichnis der Installation; Provider-Administratoren sehen einen Hinweis über jeder Seite. „Jetzt neu starten“ läuft über den Updater, startet nur die API, den Worker oder den Scheduler neu, läuft nie, während ein Update angekündigt ist oder läuft, und fragt vorher nach einer Bestätigung. Die Schaltfläche bekommt der Inhaber des Provider-Teams, und sie braucht den Updater von 0.3.6; ein älterer Updater zeigt stattdessen den Befehl. Nichts startet ohne einen Klick neu. Noch zeichnet nichts eine Neustart-Anforderung auf; Hinweis und Schaltfläche sind für Updates da, die sie brauchen.
- Der Installer aktualisiert eine alte docker-compose.yml: Wenn Sie install.sh auf einer bestehenden Installation erneut ausführen, aktualisiert es docker-compose.yml auf das Release, das in der .env steht, geprüft gegen die signierte SHA256SUMS des Releases, und behält die bisherige Datei als docker-compose.yml.bak-<timestamp>. Die .env bleibt unverändert. Eigene Änderungen gehören in docker-compose.override.yml.
Geändert
- Backup-Index: Der Platz der alten Tabelle kommt ohne Neustart zurück: Nachdem die Umwandlung des Backup-Index aus 0.3.5 abgeschlossen ist, gibt die API den Platz der alten Tabelle von selbst zurück, innerhalb von etwa 15 Minuten. Der API-Neustart, den 0.3.5 verlangte, ist nicht mehr nötig.
- Installation, Updates: Ein verfügbares Update steht neben der laufenden Version, in derselben Größe und hervorgehoben, statt nur in der Statuszeile.
- Installation, Netzlaufwerke: Läuft der Mounter nicht, beginnt der Befehl mit dem Verzeichnis der Installation; eine Compose-Datei aus der Zeit vor dem Mounter wird als solche benannt, mit dem Installer-Befehl, der sie aktualisiert.
- Repositories, Serverpfad hinzufügen: Der Dialog ist breiter und scrollt nicht mehr seitwärts.
- docker-compose.yml und .env.example behalten nur die Kommentare, die ein Leser nicht übersehen darf; die Referenz zu jeder Variable steht in der Dokumentation (docs.restowbackup.com). Inhaltlich hat sich an beiden Dateien nichts geändert.
- Abhängigkeiten: Patch- und Minor-Updates, darunter better-auth, drizzle-orm, hono, pg, nodemailer, radix-ui und vite, sowie die angepinnten GitHub Actions setup-node, upload-artifact und download-artifact.
Behoben
- Das Einbinden eines NFS-Exports, den es auf dem Server nicht gibt, endete mit einem knappen „No such file or directory“. Die Meldung nennt jetzt den Exportpfad („Der Exportpfad … existiert auf … nicht.“) und sagt, wie Sie den richtigen finden: showmount -e, bei einer Synology-NAS beginnt der Pfad mit dem Volume (/volume1/), bei NFSv4 zeigen manche Server ihre Exporte unter einer Pseudo-Root, dann hilft NFS-Version 3.
Hinweise zum Update
- Neues Image und eine Datenbankmigration (0034, eine kleine Tabelle für Neustart-Hinweise), die in Sekunden läuft. Keine neuen Pflicht-Umgebungsvariablen.
- Die Schaltfläche „Jetzt neu starten“ braucht den Updater von 0.3.6. Ein Updater von vor 0.3.6 zeigt stattdessen den Befehl, bis er das Image von 0.3.6 ausführt.
- Installationen von vor 0.3.0, deren Compose-Datei den Dienst mounter nicht hat: Führen Sie den Installer von 0.3.6 erneut aus, um sie zu aktualisieren.
- Wenn die Umwandlung des Backup-Index aus 0.3.5 noch läuft: Sie müssen nichts tun; der Platz kommt von selbst zurück, sobald die Umwandlung abgeschlossen ist.
- Rollback: Die Migration ist nicht umkehrbar; gehen Sie auf 0.3.5 nur mit dem Datenbank-Dump von vor dem Update zurück.
Bekannte Probleme
- Noch zeichnet nichts in Restow eine Neustart-Anforderung auf; Hinweis und Schaltfläche sind für Updates da, die sie brauchen.
- Der Docker-Fehlertext für einen fehlenden NFS-Export stammt aus der Dokumentation von Docker, nicht aus einem echten fehlgeschlagenen Einbinden.
- Die bekannten Probleme von 0.3.5 gelten weiter.
Verifizierung
Vor dem Tag, auf dem Release-Zweig (main plus die fünf Zweige von 0.3.6): Lint und Typecheck aller Workspaces, die Tests des Server-Installers (642), die Tests der CI- und Smoke-Werkzeuge (208) sowie die vollständigen Unit- und Postgres-Suiten auf Postgres 16: packages/db 177, packages/i18n 259, packages/core 1981, apps/scheduler 65, apps/api 3279 (1 übersprungen), apps/web 3839, apps/worker 444, ee/api 243, ee/licensing 59, ee/web 176, ee/worker 5, packages/cli 34, der Demo-Seed 208; 114 Postgres-Testdateien, keine übersprungen. Der Release-Smoke-Lauf läuft in der Release-Pipeline; vor dem Tag wurde kein Microsoft-365-Tenant verwendet.
Release-Notes von 0.3.6 auf GitHub ↗
0.3.5 beta · 14. Oktober 2026
Lässt lange erste Backups großer Postfächer nach einer Unterbrechung weiterlaufen, statt dass sie ihre Wiederholungsversuche aufbrauchen, sagt bei Proxmox VE klar, wie groß die Backups eines Gasts sind und wann eine Container-Sicherung unvollständig ist, warnt, wenn ein Rechner-Job die Ordner auslässt, in denen Linux-Dienste ihre Daten halten, und bringt die Rolle Restore-Operator. Außerdem speichert es den Backup-Index (welche Elemente jedes Backup enthält) als Elementversionen statt als vollständige Kopie je Backup, was die Datenbank großer Installationen verkleinert, und gibt der Anmeldung eine eigene Datenbankrolle. Eine Datenbankmigration, die beim Start automatisch läuft.
Neu
- Rolle Restore-Operator: Eine neue Rolle je Mandant: Der Restore-Operator sieht und stellt jedes Backup des Mandanten wieder her, ohne ihn zu verwalten (Jobs, Speicher, Benutzer). Beim Anlegen eines Benutzers oder einer Einladung muss jetzt immer eine Rolle gewählt werden; es ist keine mehr vorausgewählt.
- Proxmox VE: was ein Backup enthält und was es hinzugefügt hat: VMs & Container und das Inventar bekommen eine Spalte „Sicherung“ mit dem, was der neueste Wiederherstellungspunkt enthält und was sein Lauf hinzugefügt hat („9,4 GB im Backup, +2,5 MB neu im letzten Lauf“), mit dem ersten Backup beim Daraufzeigen. Die frühere Spalte „Größe“ heißt jetzt „Disk“. Auf der Seite eines Gasts zeigen die Wiederherstellungspunkte ihren Typ (erstes Backup, inkrementell, vollständig gelesen), was sie enthalten und was sie hinzugefügt haben. Proxmox VE bleibt eine Preview. (Jede Edition)
- Proxmox VE: unvollständige Container-Sicherungen werden benannt: Eine Container-Sicherung, die restic nicht vollständig lesen konnte, erscheint als „Mit Lücken erfolgreich“ („Letzte Sicherung unvollständig“ auf der Seite des Gasts) mit der Zahl der nicht lesbaren Elemente und zählt im Inventar als „Unvollständig“. (Jede Edition)
- Übliche Datenordner in Rechner-Jobs und im Datei-Restore: Bei Linux-Rechner-Jobs und im Datei-Restore nennt ein Hinweis die üblichen Datenordner (/opt, /srv, /var/lib, /home und weitere), die die Pfade des Jobs auslassen, mit einer Schaltfläche, um sie hinzuzufügen.
Geändert
- Proxmox VE: „Jetzt sichern“ und Restore nennen die nächste Meldung des Knotens: „Jetzt sichern“ und Restore sagen, dass der Knoten die Aufgabe bei seiner nächsten Meldung (Check-in) startet; ein zweiter Klick sagt, dass schon eine Sicherung wartet. Die Seiten aktualisieren sich alle 5 Sekunden, solange ein Gast auf seinen Knoten wartet oder gesichert wird. (Jede Edition)
- Lange erste Backups laufen nach einer Unterbrechung weiter: Ein Backup, das durch sein Zeitlimit (23 Stunden) oder durch einen Neustart des Workers unterbrochen wird, nachdem es einen Checkpoint gespeichert hat, läuft weiter, ohne einen seiner Wiederholungsversuche zu verbrauchen, bis zu 21 Tage nach seinem ersten Start. Die Laufansicht zeigt eine solche Unterbrechung als Information, nicht als Fehler. Zuvor endete das erste Backup eines großen Postfachs, das mehrere Tage brauchte, nach fünf Unterbrechungen als fehlgeschlagen, und der nächste Lauf begann von vorn.
- Microsoft 365: Eine Graph-Anfrage ohne Antwort wird wiederholt: Eine Graph-Anfrage, die innerhalb von 5 Minuten keine Antwort bekommt, wird wiederholt, statt bis zum Zeitlimit des Jobs zu hängen. Anfragen und Drosselungswartezeiten enden mit dem Job.
- Backup-Index als Elementversionen: Ein Backup kopiert nicht mehr jedes Element eines Postfachs oder OneDrives in die Datenbank. Restow führt eine Zeile je Version eines Elements, sodass ein unverändertes Element bei späteren Backups nichts kostet. Bei einer Installation mit 14 Millionen Indexzeilen (25 GB) braucht der Index danach etwa 0,5 bis 1,5 GB. Der Worker wandelt bestehende Backups nach dem Update nacheinander um; diese Umwandlung wurde an erzeugten Verläufen getestet, noch nicht an einer Produktivdatenbank von 25 GB.
- Installation: „Standard-Repository“ und „Netzlaufwerke“ sind wieder eine Seite. Alte Links auf die Netzlaufwerke öffnen sie.
- Der Worker bekommt beim Stoppen 60 Sekunden, um Checkpoints zu speichern (stop_grace_period in den Compose-Dateien, Auslaufzeit 50 Sekunden, WORKER_SHUTDOWN_TIMEOUT_MS).
- Datei-Restore: Die Dateiliste hat eine feste Höhe und scrollt in sich, sodass Pfadleiste und Aktionen an ihrem Platz bleiben.
Behoben
- Ein erstes Backup eines großen Postfachs, das mehrere Tage brauchte, endete nach fünf Unterbrechungen als fehlgeschlagen, und der nächste Lauf begann von vorn.
- „Der Lauf wurde unterbrochen“ sagte, es sei nichts verloren, auch nach dem letzten Versuch, wenn der Checkpoint verworfen wird.
- Die Datenbank von Installationen mit vielen Element-Backups (Microsoft 365) wuchs mit jedem Backup um die volle Elementzahl, bis die Platte voll war.
- Archiv: Kopfzeile, Hinweis zum Speicherschutz, Suche und Ergebnisse hatten keinen Abstand zueinander.
- Nach einem Update behauptete die Wartungsseite weiter „Restow wurde aktualisiert, diese Seite lädt jetzt neu“, wenn die Anwendung später ausfiel (zum Beispiel nach einem Neustart bei voller Platte). Nach 10 Minuten sagt sie jetzt, dass der Server vorübergehend nicht erreichbar ist.
- Die Browser-Konsole warnte bei jedem Seitenaufruf, dass drei vorgeladene Schriften in den ersten Sekunden nicht verwendet wurden. Die Schriften werden nicht mehr vorgeladen.
- Formulare meldeten keinen Fehler für ein fehlendes Feld in einer Liste (zum Beispiel die Rolle eines neuen Benutzers im Einrichtungsassistenten).
Sicherheit
- Datenbankrollen (Härtung, keine bekannte Ausnutzung): Bis 0.3.4 konnte die Datenbankrolle der Anwendung auch die Tabellen außerhalb von Row-Level-Security lesen und schreiben, darunter die Anmeldetabellen, die Installationseinstellungen, die Lizenz und die Job-Warteschlange. Ein Fehler in mandantenbezogenem Abfragecode hätte daher Daten über seinen Mandanten hinaus erreichen können. 0.3.5 verlegt die Anmeldung auf eine eigene Rolle und lässt der Anwendungsrolle nur Mandantendaten und das Hinzufügen von Jobs. Betroffen: bis 0.3.4. Außer dem Update ist nichts zu tun; die Migration ändert die Berechtigungen einer bestehenden Installation.
Hinweise zum Update
- Neues Image und eine Datenbankmigration (0033), die nur eine Tabelle anlegt und zwei Indizes entfernt und bei jeder Datenbankgröße Sekunden dauert. Keine neuen Pflicht-Umgebungsvariablen; DATABASE_AUTH_URL ist optional.
- Nach dem Start wandelt der Worker den bestehenden Backup-Index im Hintergrund um, ein Backup nach dem anderen (geschätzt etwa 15 Minuten für 14 Millionen Zeilen); Backups, Durchsuchen und Restores laufen währenddessen weiter. Sobald das Worker-Log „manifest index conversion finished“ meldet, starten Sie die api einmal neu (docker compose restart api), damit der Platz der alten Tabelle zurückgegeben wird.
- Bei fast voller Platte schaffen Sie zuerst Platz: Die Umwandlung schreibt den neuen Index, bevor der alte freigegeben wird, und der Updater schreibt vor dem Update einen Datenbank-Dump. Eine selbst gepflegte Compose-Datei braucht beim Dienst worker die Zeile stop_grace_period: 60s.
- Rollback: Die Migration ist nicht umkehrbar; gehen Sie auf 0.3.4 nur mit dem Datenbank-Dump von vor dem Update zurück.
Bekannte Probleme
- Die Umwandlung des Backup-Index im Hintergrund wurde an erzeugten Verläufen getestet, noch nicht an einer Produktivdatenbank von 25 GB; wie lange sie dort dauert, ist eine Schätzung.
- Die bekannten Probleme von 0.3.4 gelten weiter.
Verifizierung
Vor dem Tag, auf dem Release-Zweig: CI grün (Lint, Typecheck, Build, Docker-Images, Go-Agent, Lizenzen, Secret-Scan sowie die Unit- und Postgres-Suiten auf Postgres 16 mit Passwort-Authentifizierung). Vor dem Tag wurde kein Microsoft-365-Tenant verwendet.
Release-Pipeline vom 14. Oktober 2026: 10 von 11 Prüfungen vollständig bestanden, 1 übersprungen, 0 fehlgeschlagen. Übersprungen wurde Prüfung 4, Microsoft-365-Backup und -Restore gegen den Dev-Tenant. Die Community-Images wurden für sich getestet: 8 von 11 Prüfungen vollständig bestanden und 3 übersprungen, auf amd64 und auf arm64. Der vollständige Bericht mit dem Grund jeder übersprungenen Prüfung hängt als smoke-report.md am Release.
Release-Notes von 0.3.5 auf GitHub ↗
0.3.4 beta · 11. Oktober 2026
Ein Hotfix: Proxmox-VE-Container-Sicherungen scheitern nicht mehr am Ordner lost+found eines nicht privilegierten Containers, VMs & Container zeigen, wenn eine Sicherung auf ihren Knoten wartet oder läuft, und ein kurzer Aussetzer, während der Browser die Anmeldung neu prüft, ersetzt nicht mehr die ganze Oberfläche durch „Restow konnte nicht geladen werden“. Keine Datenbankmigration.
- Proxmox VE: nicht privilegierte Container: Sicherungen nicht privilegierter Container auf ext4 scheitern nicht mehr am Ordner lost+found. Eine Container-Sicherung, die restic nicht vollständig lesen konnte (Exit-Code 3), behält ihren Sicherungsstand und nennt die nicht lesbaren Elemente. VMs & Container zeigen, wenn eine Sicherung auf ihren Knoten wartet oder läuft. Nach dem Server-Update auf jedem Knoten restow-pve update ausführen. (Jede Edition)
Hinweise zum Update
- Neues Image und ein neuer restow-pve-Helfer für die Proxmox-VE-Knoten; keine Datenbankmigration. Führen Sie nach dem Server-Update auf jedem Knoten restow-pve update aus, damit die Container-Korrektur dort greift; der Server-Teil arbeitet auch mit älteren Helfern.
Bekannte Probleme
- Die Knotenzeilen des Inventars zeigen noch nicht, dass eine Sicherung auf den Knoten wartet oder läuft; VMs & Container tut das.
- Die bekannten Probleme von 0.3.3 gelten weiter.
Verifizierung
Release-Pipeline vom 11. Oktober 2026: 10 von 11 Prüfungen vollständig bestanden, 1 übersprungen, 0 fehlgeschlagen. Übersprungen wurde Prüfung 4, Microsoft-365-Backup und -Restore gegen den Dev-Tenant. Die Community-Images wurden für sich getestet: 8 von 11 Prüfungen vollständig bestanden und 3 übersprungen, auf amd64 und auf arm64. Der vollständige Bericht mit dem Grund jeder übersprungenen Prüfung hängt als smoke-report.md am Release.
Release-Notes von 0.3.4 auf GitHub ↗
0.3.3 beta · 10. Oktober 2026
Zeigt die Proxmox-VE-Knoten mit ihren VMs und Containern im Inventar, bindet ein NFS-Netzlaufwerk direkt aus dem Pfadfeld eines Repositorys ein und nennt den Ort, an dem Sicherungen liegen, überall „Repository“. Keine Datenbankmigration.
- Repositories: eine NFS-Adresse im Pfadfeld: Das Pfadfeld eines Verzeichnis-Repositorys nimmt eine NFS-Adresse an (192.168.1.10:/export/backup, nas.local:/volume1/restow oder nfs://). Der Provider-Inhaber kann sie dort testen und einbinden, und Restow trägt den Pfad ein; laufen Jobs, wartet das Einbinden, bis keiner läuft, und lässt sich abbrechen. Ein Menüeintrag Repositories steht unter Ihrer Organisation, und die Oberfläche sagt überall Repository statt Speicherort. Gegen die Attrappen des Mounters getestet, noch nicht gegen einen echten NFS-Server; solange ein Einbinden wartet, starten neue Jobs weiter.
- Proxmox-VE-Knoten im Inventar: Unter Server & Clients, Inventar ist jeder Proxmox-VE-Knoten eine aufklappbare Zeile mit seinem Online-Zustand und Zahlen (geschützt, fehlgeschlagen, kein Job, noch nicht gesichert); aufgeklappt zeigt jede VM und jeder Container Status, Backup-Job und Sicherungszustand sowie den Grund, warum die letzte Sicherung fehlschlug, verlinkt auf seine Seite. Für Administratoren, sobald ein Cluster verbunden ist. (Jede Edition)
Sicherheit
- Die Dependabot-Meldungen sind abgearbeitet (uuid, esbuild und vitest, die beiden letzten nur für die Entwicklung). Keiner der verwundbaren Codepfade war in Restow erreichbar.
Hinweise zum Update
- Neues Image; keine Datenbankmigration. Wer von 0.3.0 oder älter kommt, liest die Hinweise zu 0.3.2 und 0.3.1.
Bekannte Probleme
- Das Einbinden eines NFS-Netzlaufwerks aus dem Pfadfeld wurde gegen die Attrappen des Mounters getestet, noch nicht gegen einen echten NFS-Server. Solange ein Einbinden auf laufende Jobs wartet, starten neue Jobs weiter; auf einem Server, der nie ruht, wartet es also weiter.
- Die bekannten Probleme von 0.3.2 gelten weiter.
Verifizierung
Release-Pipeline vom 10. Oktober 2026: 10 von 11 Prüfungen vollständig bestanden, 1 übersprungen, 0 fehlgeschlagen. Übersprungen wurde Prüfung 4, Microsoft-365-Backup und -Restore gegen den Dev-Tenant. Die Community-Images wurden für sich getestet: 8 von 11 Prüfungen vollständig bestanden und 3 übersprungen, auf amd64 und auf arm64. Der vollständige Bericht mit dem Grund jeder übersprungenen Prüfung hängt als smoke-report.md am Release.
Release-Notes von 0.3.3 auf GitHub ↗
0.3.2 beta · 10. Oktober 2026
Bindet einen Proxmox-VE-Knoten mit einem Befehl und ohne Eingaben an und behebt Microsoft-365-Postfach-Sicherungen, die im Ordnerschritt mit „Microsoft hat die Anfrage abgelehnt“ (HTTP 400) stehen blieben. Beim Update läuft eine Datenbankmigration.
- Proxmox-VE-Knoten mit einem Befehl anbinden: Ein Befehl je Knoten, mit dem Enrollment-Token darin. Der Knoten-Installer richtet den Benutzer restow@pve, die Rollen und den Restore-Pool selbst ein, legt einen eigenen API-Token an, prüft seine Rechte, bevor er etwas installiert, und wählt den Thin-Speicher für Fleecing selbst. Stattdessen lässt sich ein vorhandener Proxmox-VE-API-Token verwenden, der dem Knoten einmal übergeben wird. Das Storage-Plugin meldet die Storage-API des laufenden Proxmox VE (8.4 bis 9.1). Gegen Attrappen für pveum und pvesm getestet; Proxmox VE ist eine Preview und wird als einzige Sicherung noch nicht empfohlen. (Jede Edition)
- Microsoft-365-Postfach-Backups bleiben im Ordnerschritt nicht mehr stehen: Eine Postfach-Sicherung konnte im Ordnerschritt mit „Microsoft hat die Anfrage abgelehnt“ scheitern (HTTP 400, eine ID, die in einem Batch eindeutig sein muss), wenn Microsoft beim Lesen der Ordnerliste einen Ordner doppelt aufführte. Jeder Batch nutzt jetzt eigene IDs, und jeder Ordner wird einmal gelesen.
Hinweise zum Update
- Neues Image; eine Migration, 0032_pve_enrollment_pve_token (ergänzt eine Spalte; sofort erledigt). Wer von 0.2.x kommt, liest zuerst die Hinweise zu 0.3.1.
- Mit 0.3.1 angebundene Proxmox-VE-Knoten laufen weiter. Für das neue Storage-Plugin (keine Warnung mehr unter Proxmox VE 9) führen Sie auf jedem Knoten restow-pve update aus.
Bekannte Probleme
- Die neue Proxmox-VE-Anbindung wurde gegen Attrappen für pveum und pvesm getestet, noch nicht auf einem Proxmox-VE-Host.
- Die bekannten Probleme von 0.3.1 gelten weiter.
Verifizierung
Release-Pipeline vom 10. Oktober 2026: 10 von 11 Prüfungen vollständig bestanden, 1 übersprungen, 0 fehlgeschlagen. Übersprungen wurde Prüfung 4, Microsoft-365-Backup und -Restore gegen den Dev-Tenant. Die Community-Images wurden für sich getestet: 8 von 11 Prüfungen vollständig bestanden und 3 übersprungen, auf amd64 und auf arm64. Der vollständige Bericht mit dem Grund jeder übersprungenen Prüfung hängt als smoke-report.md am Release.
Die Release-Notes auf GitHub tragen das Datum 9. Oktober 2026; veröffentlicht wurde das Release am 10. Oktober. Release-Notes von 0.3.2 auf GitHub ↗
0.3.1 beta · 8. Oktober 2026
Das erste Release der 0.3er-Linie: 0.3.0 wurde getaggt, aber nie veröffentlicht, weil seine Release-Prüfungen die ersten beiden Fehler fanden. Sichert virtuelle Maschinen und Container von Proxmox VE (Preview), bindet NFS-Netzlaufwerke über die Weboberfläche ein, lässt Community mehrere Administratoren betreiben und sendet Benachrichtigungen an Discord, Slack und Teams sowie über Microsoft 365 oder Google Workspace. Übersicht, Backup-Jobs und Archiv sagen jetzt klar, was geschützt ist und was nicht. Beim Update laufen sechs Datenbankmigrationen.
- Proxmox VE (Preview): Backup von VMs und Containern auf Proxmox VE ab 8.4 über die Backup-Provider-API: VM-Festplatten über NBD mit Dirty Bitmaps, sodass nur geänderte 4-MiB-Blöcke hochgeladen werden; Container über restic; Restore als neue VMID in den Pool restow-restore. Gäste zählen bei Wiederherstellbarkeit, Warnungen und Alarmen für überfällige Sicherungen mit. Die Knotenseite ist ein Storage-Plugin-Shim (ein eigenes Werk unter AGPL-3.0-or-later) und der Helfer restow-pve (Apache-2.0). Eine Preview: gegen qemu-nbd, qemu-img und restic getestet; als einzige Sicherung noch nicht empfohlen. (Jede Edition)
- Mehrere Administratoren in jeder Edition: Mitglieder mit Rollen, auch in Community; ein Mitglied auf ausgewählte Mandanten zu beschränken bleibt Teil von Service Provider. Inhaber können den Zugang eines Mitglieds zurücksetzen. Bevor eine Änderung der öffentlichen URL oder des Betriebsmodus Passkeys unbrauchbar macht, nennen die Einstellungen die betroffenen Konten und verweigern eine Selbstaussperrung. Bei verlorenem Zugang bietet die Anmeldeseite einen Zurücksetzen-Link per Mail, wenn die Benachrichtigungs-Mail eingerichtet ist, und immer den Weg über einen Inhaber oder restow admin recover. Ihr Konto: Passwort ändern, Sitzungen sehen und beenden.
- NFS-Netzlaufwerke über die Weboberfläche: Unter Installation, Netzlaufwerke über den optionalen Mounter-Container (docker compose --profile mounts up -d mounter oder die Installer-Option --with-mounter): Der Mounter prüft ein Netzlaufwerk, bevor er docker-compose.override.yml schreibt, startet api und worker neu und rollt bei einem Fehler zurück; der Updater zieht ihn bei jedem signierten Update mit. Nur gegen Attrappen getestet, nicht gegen einen echten NFS-Server.
- Alarme in Discord, Slack und Microsoft Teams: Ein Webhook bekommt ein Format, gewählt anhand seiner URL: Discord, Slack oder Microsoft Teams, neben dem signierten Restow-Umschlag. 4xx-Antworten von Chat-Diensten beenden eine Zustellung sofort, statt sie zu wiederholen. Nur gegen Attrappen getestet.
- Überfällige Sicherungen und Warnungen: Ein neues Ereignis, backup.overdue, für Postfächer, OneDrives, IMAP-Konten, Rechner und Proxmox-Gäste, das die Zeitpläne der Backup-Jobs berücksichtigt; eine Alarmregel kann eine eigene Frist setzen (24 bis 720 Stunden). Warnungen nennen, warum einzelne Elemente nicht gesichert wurden (Ordner, Betreff, Datum, Ursache, was zu tun ist), und lassen sich mit einer Notiz bestätigen. Die Glocke führt zur Ursache, und eine Seite Benachrichtigungen bewahrt den Verlauf.
- Benachrichtigungs-Mail über Microsoft 365 oder Google Workspace: Die Benachrichtigungs-Mail lässt sich über Microsoft 365 (eine eigene App mit Mail.Send oder die Backup-App) oder über Google Workspace (ein Dienstkonto mit gmail.send) senden, mit Anleitungen und klaren Fehlermeldungen. Nur gegen Attrappen getestet.
- Audit-Log-Export: Export des Audit-Logs als CSV und als JSON mit Hashes. Die Zustellprotokolle lassen sich als CSV exportieren. (Business, Service Provider)
- Archiv je Mail-Job, Lesen und Suche: Archiv je Mail-Job; Journalberichte werden den Postfächern zugeordnet, die sie nennen. Die Kettenprüfung verifiziert jedes Glied, die täglichen Anker (jetzt jede Nacht geschrieben) und auf Wunsch eine Stichprobe der Nachrichteninhalte. Archivierte Nachrichten lassen sich lesen und als .eml herunterladen; die Suche blättert durch ihre Ergebnisse und filtert nach Absender, Datum und Postfach; ein Hinweis sagt, wie der Speicher archivierte Mail schützt.
- Legal Hold mit protokollierter Aufhebung: Ein Legal Hold wird mit einer verpflichtenden, protokollierten Begründung aufgehoben; Holds können ein einzelnes Postfach betreffen. (Business, Service Provider)
- Klar sagen, was geschützt ist: Rechner, die in keinem Backup-Job sind, zählen nirgends mehr als geschützt (Übersicht, Provider-Ansicht, Wiederherstellbarkeit, Berichte). Das Verzeichnis, die Backup-Jobs und die Rechner sagen, welcher Job ein Objekt sichert, und nennen Objekte in pausierten oder nicht geplanten Jobs. Übersicht, Statistik zeigt nur den aktiven Mandanten; die Statistik aller Mandanten hat für Service Provider eine eigene Seite.
Inkompatible Änderungen
- Rechner, die in keinem Backup-Job sind, zählen nirgends mehr als geschützt (Übersicht, Provider-Ansicht, Wiederherstellbarkeit, Berichte). Installationen, die sich auf die alte Zählung verlassen haben, sehen mehr Gelb: Nehmen Sie die Rechner in einen Backup-Job auf.
- Übersicht, Statistik zeigt nur den aktiven Mandanten. Die Statistik aller Mandanten ist auf eine eigene Seite umgezogen (Service Provider); alte Links mit scope=provider führen dorthin.
- Ein auf einige Mandanten beschränktes Provider-Mitglied kann die Summen der Statistik aller Mandanten nicht mehr lesen (403).
- Integrations-API, Vertrag 1.3.0 (additiv): Webhooks tragen format.
Sicherheit
- Ein auf einige Mandanten beschränktes Provider-Mitglied konnte die Summen der Statistik und die Mandantentabelle aller Mandanten lesen (Service Provider mit mandantenbeschränkten Mitgliedern, bis 0.2.2). Behoben; außer dem Update ist nichts zu tun.
Hinweise zum Update
- Sechs Datenbankmigrationen (0026 bis 0031) laufen beim Start. Die Einrichtungsmitteilung hat sich geändert: Jede Installation bittet ihren Provider-Admin einmal, sie erneut zu bestätigen.
- docker-compose.yml bekommt den Dienst mounter im Profil mounts; ersetzen Sie Ihre Compose-Datei durch die dieses Releases (der Updater erledigt das für Sie).
- Rollback: den vor dem Update gezogenen Datenbank-Dump einspielen und die 0.2.2-Images starten; Migrationen sind nicht umkehrbar.
Bekannte Probleme
- Proxmox VE wurde gegen echte qemu-nbd, qemu-img und restic getestet, aber noch nicht auf einem Proxmox-VE-Host; behandeln Sie es als Preview.
- NFS-Einbindungen, die Benachrichtigungs-Mail über Microsoft 365 und Google sowie die Chat-Webhooks wurden nur gegen Attrappen getestet.
- Die Unveränderbarkeit des Archivs auf lokalem und NFS-Speicher erzwingt nur die Anwendung.
Verifizierung
Release-Pipeline vom 8. Oktober 2026: 10 von 11 Prüfungen vollständig bestanden, 1 übersprungen, 0 fehlgeschlagen. Übersprungen wurde Prüfung 4, Microsoft-365-Backup und -Restore gegen den Dev-Tenant. Die Community-Images wurden für sich getestet: 8 von 11 Prüfungen vollständig bestanden und 3 übersprungen, auf amd64 und auf arm64. Der vollständige Bericht mit dem Grund jeder übersprungenen Prüfung hängt als smoke-report.md am Release.
Release-Notes von 0.3.1 auf GitHub ↗
0.2.2 beta · 6. Oktober 2026
Lässt jede Microsoft-365-Quelle entweder über die Zustimmungseinladung oder über eine eigene Graph-App anbinden, verbindet den Tenant, in dem die Backup-App liegt, ohne Zustimmungslink, korrigiert das Hetzner-Object-Storage-Preset und die Object-Lock-Erkennung und ergänzt den Reiter Updates um einen Alpha-Kanal für Testbuilds. Keine Migration und kein manueller Schritt.
- Eigene Graph-App je Quelle: Neben der Zustimmungseinladung der gemeinsamen Backup-App lässt sich eine Quelle über eine App verbinden, die der Kunde von Hand im eigenen Tenant angelegt hat: Tenant-ID, Anwendungs-ID und ein Client-Geheimnis oder Zertifikat. Die Zugangsdaten werden im Geheimnisspeicher der Organisation versiegelt und nie wieder angezeigt. Getestet nur mit Unit-Tests und den CI-Suiten, nicht gegen einen echten Microsoft-365-Mandanten.
- Der Tenant der Backup-App lässt sich ohne Zustimmungslink verbinden: Für den Tenant, in dem die Backup-App liegt, bietet die Quellenseite eine direkte Verbindung (nur Provider-Inhaber): Ein funktionierendes App-Token für diesen Tenant dient als Nachweis, sodass der Zustimmungs-Umweg entfällt, den Entra für eine dort nicht installierte App ablehnt. Dafür braucht es die Verzeichnis-ID (Tenant-ID) der App unter Einstellungen, Microsoft 365.
- Hetzner-Object-Storage-Preset mit Standortwahl: Das Preset hat eine Standortauswahl (Falkenstein, Nürnberg, Helsinki), die Endpunkt und Region zusammen setzt. Buckets mit einem Punkt im Namen werden über den Pfad angesprochen, und die Object-Lock-Erkennung akzeptiert die Antworten S3-kompatibler Dienste wie Hetzner. Nicht gegen einen echten Hetzner-Bucket getestet.
- Alpha-Kanal für Testbuilds: Unter Installation, Updates wählt die Option für den Alpha-Kanal mit einem Klick eine Quelle unsignierter Testbuilds. Der Reiter warnt, solange sie gewählt ist und solange der Updater keine Signaturen prüft. Nur für Testinstallationen, nie für eine mit Produktivdaten.
Bekannte Probleme
- Die Verbindung über eine eigene Graph-App und die direkte Verbindung des Heimat-Tenants wurden nur mit Unit-Tests und den CI-Suiten getestet, nicht gegen einen echten Microsoft-365-Tenant. Der Hetzner-Preset und die Object-Lock-Erkennung wurden nicht gegen einen echten Hetzner-Bucket getestet.
- Eine per Zustimmung verbundene Quelle lässt sich in der Oberfläche nicht auf eine eigene Graph-App umstellen.
Verifizierung
Release-Pipeline vom 6. Oktober 2026: 10 von 11 Prüfungen vollständig bestanden, 1 übersprungen, 0 fehlgeschlagen. Übersprungen wurde Prüfung 4, Microsoft-365-Backup und -Restore gegen den Dev-Tenant. Die Community-Images wurden für sich getestet: 8 von 11 Prüfungen vollständig bestanden und 3 übersprungen, auf amd64 und auf arm64. Der vollständige Bericht mit dem Grund jeder übersprungenen Prüfung hängt als smoke-report.md am Release.
Release-Notes von 0.2.2 auf GitHub ↗
0.2.1 beta · 3. Oktober 2026
Bringt zu Ende, was 0.2.0 begonnen hat: Rechner werden über Jobs gesichert, Tabellen bekommen Kontextmenüs, und der Datei-Restore legt Rechner und Postfächer auf eine Zeitleiste.
- Ein Rechner sichert, sobald er in einem Job ist: Jeder Rechner ohne Backup-Job ist mit „Ohne Backup“ markiert, wird in einem Banner gezählt und bekommt „Job anlegen“ oder „Zu Job hinzufügen…“ angeboten. Ein neu angemeldeter Rechner wartet auf einen Job, statt eigenmächtig zu sichern. Server sichern standardmäßig ihre Anwendungsdaten (/opt, /usr/local, /var/lib).
- Kontextmenüs auf Tabellenzeilen: Rechtsklick oder die ⋯-Schaltfläche auf einer Tabellenzeile öffnet die Aktionen dieser Zeile: neuer Job aus der Auswahl, Job bearbeiten, jetzt ausführen, Verlauf öffnen, Dateien eines Rechners wiederherstellen.
- Rechnertabelle mit "Zugeordnet zu": Eine Tabelle aller Rechner mit Hostname, der Person, der der Rechner zugewiesen ist, letzter Sicherung und Wiederherstellbarkeit. Ein Rechner lässt sich einer Person aus dem Verzeichnis zuweisen.
- Datei-Restore aus der Rechnertabelle, eine Zeitleiste: Der Datei-Restore beginnt mit der Rechnertabelle. Wiederherstellungspunkte von Rechnern und Postfächern liegen auf derselben Zeitleiste, mit Tagestrennern, Uhrzeiten und einem Sprung zu einem Datum.
- Öffentliche Demo mit simulierten laufenden Jobs: Die öffentliche Demo zeigt laufende Sicherungen mit Fortschritt, Durchsatz-Diagrammen und dem Detailpanel zum Lauf, simuliert auf synthetischen Daten.
- Standardspeicher in der Weboberfläche: Der Inhaber der Installation legt den Standardspeicher (einen lokalen Pfad oder einen S3-kompatiblen Bucket) unter Installation > Standardspeicher fest, geprüft durch einen Test vor dem Speichern. Mandanten darauf bleiben durch eigenes Präfix und eigenen Schlüssel getrennt.
- Updater mit einem Befehl, der sich selbst aktualisiert: Der optionale Updater startet mit einem Befehl und zieht sich nach einem signierten Update selbst auf das geprüfte Release nach. Eine Community-Installation wechselt unter Installation > Edition zum vollständigen Build, mit Datenbank-Dump, Health-Check und Rollback.
Inkompatible Änderungen
- Ein Rechner, der in keinem Backup-Job ist, wird nicht gesichert. Neu angemeldete Rechner und Rechner, die ihren Job verlassen, warten auf einen Job; Rechner ohne Job zum Zeitpunkt des Updates behalten ihre eigene Konfiguration.
- API: Sicherungen eines Rechners brauchen einen Job. backup_now und ein Zeitplan außer none antworten 409 endpoint-no-job für einen Rechner ohne Job.
Hinweise zum Update
- Eine additive Datenbankmigration (0025_endpoint_assigned_user); nichts wird gelöscht.
- Wer den Updater unter 0.2.0 eingeschaltet hat, ersetzt docker-compose.yml durch die des Releases 0.2.1, bevor oder während er aktualisiert.
- Agents vor 0.2.1 kennen den Zeitplan none nicht und melden bis zu ihrem Selbst-Update fehlgeschlagene no_paths-Läufe; es wird nichts gelesen oder geschrieben.
- SMB/CIFS wird nicht mehr als unterstützter Speicher-Mount genannt; Netzwerkspeicher für lokale Ziele ist NFS. Bestehende eingebundene Pfade funktionieren weiter.
- Rollback: die 0.2.0-Images plus der Datenbank-Dump von vor dem Update, weil eine Migration gelaufen ist.
Release-Notes von 0.2.1 auf GitHub ↗
0.2.0 beta · 3. Oktober 2026
Ordnet die Weboberfläche nach drei Ebenen (Installation, ein Mandant, alle Mandanten), ergänzt Backup-Jobs, die Zeitpläne je Objekt ersetzen, und zeigt laufende Sicherungen live. Das Update von 0.1.0 führt drei additive Migrationen aus und überführt Zeitpläne und Rechner in Jobs, ohne etwas zu löschen.
- Installation, eigene Organisation und Mandanten-Einstellungen: Jede Einstellung hat einen Ort und eine Ebene: die Installation (Server, Benachrichtigungs-Mail, Updates, Lizenz) und je Mandant eine Einstellungsseite (Verbindungen, Schutz, Jobs, Aufbewahrung, Repositories, Archiv, Agents, Benachrichtigungen, Integrationen, Mitglieder, Module), anstelle der Reiterleiste Einrichtung aus 0.1.0. Für Service Provider legt die Einrichtung die eigene Organisation als internen Mandanten an. Ein Modul auszuschalten pausiert seine Arbeit und löscht nie Daten.
- Mandanten-Umschalter mit Suche im Menü: Zwischen Mandanten wechseln Sie oben im Menü, und per Suche finden Sie einen nach Name oder Kundennummer. (Service Provider)
- Farbschema Restow oder Neutral neben Hell und Dunkel: Wählen Sie zwischen den Restow-Farben und einer neutralen Palette, zusätzlich zum hellen und dunklen Modus.
- Tabellen in voller Breite mit fixierten Spalten: Tabellen nutzen die volle Seitenbreite, und fixierte Spalten bleiben sichtbar, während Sie seitlich scrollen.
- Geführter Installer mit Reverse-Proxy-Modus, standardmäßig verschlüsselt zu Restow: Ein Installer, der Sie durch die Installation führt, mit einem Modus für den Betrieb hinter einem Reverse-Proxy. Die Verbindung zu Restow ist standardmäßig verschlüsselt.
- Einrichtungsassistent beginnt mit der Sprachwahl: Der Einrichtungsassistent beginnt jetzt mit der Wahl der Sprache.
- Erste Schritte als Checkliste im Menü: Ein Raketen-Eintrag unten links im Menü öffnet die Einrichtungs-Checkliste: funktionierendes Repository, verbundene Quelle, geschützte Objekte, aktive Zeitpläne, erste Sicherung und erste bestandene Restore-Prüfung, dazu die Benachrichtigungs-Mail, die sich als nicht nötig markieren lässt. Sobald die Einrichtung abgeschlossen ist, verschwindet der Eintrag.
- Wiederherstellbarkeit verknüpft mit gefilterten Tabellen: Jeder Zustand der Wiederherstellbarkeit (bestanden, fällig, nicht abgeschlossen und wiederholt, fehlgeschlagen, Sicherung zu alt, nie geprüft) filtert die Tabelle darunter.
- Übersicht über alle Mandanten oder einen Mandanten: Die Übersicht zeigt alle Mandanten auf einmal oder einen einzelnen Mandanten, ganz wie Sie wählen. (Service Provider)
- Jobs als Vorlagen: Ein Job legt fest, was gesichert wird, wann, in welches Repository, wie lange und wie oft eine Restore-Prüfung es nachweist, für viele Postfächer, OneDrives, IMAP-Konten oder Rechner zugleich, mit Abweichungen je Objekt oder Rechner. Es gibt Jobs für Mail und für Server und Clients; für Server und Clients wählen Sie die zu sichernden Ordner aus und schließen Dateitypen aus. Beim Update werden die heutigen Zeitpläne und Rechner-Einstellungen zu Jobs; nichts wird gelöscht.
- Live-Aktualisierung ohne Neuladen, Detailpanel zum Lauf mit Durchsatz-Diagrammen: Laufende Jobs und Tabellen aktualisieren sich von selbst, ohne dass Sie die Seite neu laden. Ein Lauf öffnet ein Detailpanel mit Diagrammen seines Durchsatzes.
- Bandbreitenlimit mit Zeitfenster: Begrenzen Sie die Bandbreite, die ein Backup nutzen darf, innerhalb eines Zeitfensters, das Sie festlegen.
- Verlauf einschließlich Agent-Läufen: Jeder Lauf, auch die Läufe der Agents auf Servern und Clients, mit Filtern nach Art (Backup, Restore, Restore-Prüfung, Export, Import, Wartung) und nach Job. Die Wiederholungen einer Restore-Prüfung erscheinen als eine Zeile.
Inkompatible Änderungen
- POST /api/v1/setup verlangt providerName, den Namen der eigenen Organisation.
- Backup- und Restore-Prüfungs-Zeitpläne entstehen über Jobs: POST /api/v1/schedules mit kind backup oder verify antwortet 422 kind_replaced_by_jobs. Wartungszeitpläne bleiben unverändert.
- Ein Rechner in einem Job wird über den Job konfiguriert: PATCH /api/v1/endpoints/:id antwortet 409, wenn es Ordner, Ausschlüsse, Hooks, Bandbreite oder Zeitplan ändern würde.
- Alte Adressen der Weboberfläche leiten auf ihren neuen Ort um; Lesezeichen und Links in Mails funktionieren weiter.
Release-Notes von 0.2.0 auf GitHub ↗
0.1.0 beta · 2. Oktober 2026
Erstes öffentliches Release.
- Microsoft-365-Backup: Exchange-Online-Mail, Kalender und Kontakte sowie OneDrive, inkrementell per Graph-Delta-Abfragen.
- IMAP-Backup: Beliebige IMAP-Postfächer, mit Passwort: ein Login für die ganze Quelle, ein Passwort je Postfach oder ein Master-User. OAuth2-Anmeldung für IMAP ist noch nicht umgesetzt.
- Nicht-destruktiver Restore: Einzelnes Element, Ordner, Dateiversion oder ganzes Postfach bzw. OneDrive, ins Ursprungskonto oder ein anderes. Der Restore-Explorer zeigt unten eine schmale Zeitleiste der Wiederherstellungspunkte.
- Wöchentliche Restore-Prüfung: Eine Stichprobe aus jedem Backup wird zurückgelesen und Byte für Byte verglichen, angezeigt als Wiederherstellbarkeit.
- Archiv: Ein nur anhängbares Archiv mit SHA-256-Hash-Kette, Kettenprüfung, Suche und Export (EML in einer ZIP-Datei, MBOX), in jeder Edition. Die Suche umfasst Betreff, Adressen und den Nachrichtentext importierter Mail, keine Anhänge. Gefüllt wird es durch Mail-Import mit Archivierung; der Empfang von Journalberichten gehört zur GoBD-Schicht unten.
- GoBD-Schicht für das Archiv: Empfang von Exchange-Online-Journalberichten per SMTP (braucht ein eigenes TLS-Zertifikat), Aufbewahrungsrichtlinien mit durchgesetztem Löschlauf und Legal Hold je Mandant oder je Postfach. Für den GoBD-konformen Einsatz ausgelegt. Auf lokalen und NFS-Repositories erzwingt die Anwendung die Unveränderbarkeit; auf S3 mit Object Lock sind die Datensätze der Archivelemente gesperrt, und seit 0.4.0 kann ein Administrator auch die Packs mit dem Nachrichteninhalt sperren (siehe Unveränderbare Backups). (Business, Service Provider)
- Mehrere Mandanten: Viele Kundenmandanten in einer Installation, mit mandantenübergreifendem API-Schlüssel. Mehrere Mandanten zu verwalten gehört zu Service Provider. (Service Provider)
- Delegierte Mandanten-Admins und Provider-Übersicht: Jeder Mandant hat eigene Administratoren, die nur diesen Mandanten sehen und verwalten. Die Provider-Ansicht der Übersicht listet jeden Mandanten mit seinem Status und den daraus folgenden Alarmen. (Service Provider)
- REST-API und Betriebsprotokoll: REST-API mit OpenAPI-Doku, Schlüsseln und Scopes je Mandant; Jobverlauf und Fehler in jeder Edition.
- Team mit Rollen: Mehrere Administratoren, jeweils Inhaber, Administrator, Techniker oder Nur lesen, mit allen oder ausgewählten Mandanten. Inhaber laden ein und ändern Mitglieder; jede Änderung wird protokolliert. Business und Service Provider hatten das ab 0.1.0, jede Edition hat es seit 0.3.1 (siehe 0.3.1 bis 0.3.6).
- Audit-Log-Ansicht: Suche, Filter, Eintragsdetails und Prüfung der Hash-Kette des Audit-Logs. Die Aufzeichnung jedes Lesens und Wiederherstellens läuft in jeder Edition; der Export kam mit 0.3.1. (Business, Service Provider)
- Zeitgesteuerte Berichte: Eine tägliche, wöchentliche oder monatliche Zusammenfassung per E-Mail: Erfolgsquote, fehlgeschlagene Elemente, Anteil nachweislich wiederherstellbar, Fehlerursachen, Speicher und Wiederherstellungen. (Business, Service Provider)
- Alarme: Regeln, die eine E-Mail, einen Eintrag in der Glocke oder einen signierten Webhook senden, wenn eine Sicherung fehlschlägt, eine Restore-Prüfung nicht besteht oder Speicher beschädigt ist, mit Zustellprotokoll.
- Server- und Client-Backup: Ein Go-Agent für Linux und macOS auf Basis von restic 0.19.1, eingerichtet mit einem Befehl und einem Einmal-Token, installiert in einen Ordner, den nur root ändern kann. Signierte Agent-Releases, nur ausgehendes HTTPS, nur anhängend, ein Repository je Rechner, Restore in einen neuen Ordner, Restore-Tests, die in die Wiederherstellbarkeit einfließen. Hooks laufen nur, wo root auf dem Rechner sie erlaubt. Windows ist geplant.
- Mail-Import und -Export: EML, MSG, MBOX und MailStore-Exporte als Altpostfach importieren, das Sie durchsuchen, in Microsoft 365 oder IMAP wiederherstellen, herunterladen und optional archivieren können. Postfächer aus Backups, Importen und dem Archiv als EML in einer ZIP-Datei oder als MBOX exportieren.
- Updates: Eine Update-Prüfung, die aus ist, bis Sie sie einschalten, auf Wunsch mit eigener Release-Quelle, und ein optionaler Updater, der Wartung ankündigt, zuerst die Datenbank sichert und zurückrollt, wenn die neue Version nicht gesund startet. Das Rollback gilt nur, solange die Datenbankmigrationen noch nicht gelaufen sind; nach einer Migration hält der Updater an, behält den Dump und sagt, wie Sie ihn einspielen.
- Fehlererklärungen: Jeder fehlgeschlagene Job, jedes Element, jeder Abgleich und jede Prüfung sagt, was passiert ist, warum (88 stabile Ursachencodes) und was zu tun ist, mit Links und technischen Details für den Support.
- Signierte, geprüfte Releases: Jedes Release erscheint in zwei Builds mit vier Images: dem vollständigen Build (restow, restow-web) und dem Community-Build (restow-community, restow-web-community). Jedes Image wird für amd64 und arm64 gebaut, mit cosign signiert, liefert eine SBOM mit und besteht einen Release-Smoke-Lauf (Neuinstallation, Restores mit Hash-Vergleich, Endpoint-Backup, Mail-Import, Freigaben-Backup gegen Samba), bevor es veröffentlicht wird. Jedes Agent-Release signiert der Maintainer mit einem Ed25519-Schlüssel; Installer und Agent lehnen ein Release ohne gültige Signatur ab. Die automatisierte Microsoft-365-Prüfung der Release-Pipeline gegen einen echten Mandanten (Prüfung 4, ein Dev-Tenant) ist noch nicht aktiv und wurde in jedem bisherigen Release übersprungen; eine simulierte Graph-API ersetzt sie. In den Release-Prüfungen läuft der Agent-Installer nur in einem Linux-Container.
- Setup-Token, Betreiberhinweis, zwei Builds: Der Einrichtungsassistent fragt zuerst nach einem einmaligen Setup-Token, das nur lesen kann, wer Zugriff auf das Log des Servers hat, und dann nach der Bestätigung eines Betreiberhinweises. Der Kern (Apache License 2.0) und die Business- und Service-Provider-Module (ee/, unter den Restow-Lizenzbedingungen) liegen in einem Repository. Die vollständigen Images enthalten beides, die Module gesperrt, bis ein Lizenzschlüssel installiert ist; die Community-Images enthalten nur den Kern.
Bekannte Grenzen
- Teams ist nicht Teil von Version 1; SharePoint-Online-Websites kamen mit 0.4.0 dazu.
- OAuth2 für IMAP-Quellen ist noch nicht umgesetzt; geplant. IMAP-Quellen melden sich mit Passwort an: je Quelle mit einer gemeinsamen Anmeldung, einem Passwort je Postfach oder einem Master-Konto.
- Das erste Backup eines großen Mandanten kann Tage dauern, weil Microsoft die Graph-API drosselt; Restow zeigt diese Wartezeit an.
- Microsoft-365-Backup und -Restore wurden in den Release-Prüfungen noch nicht gegen einen echten Microsoft-365-Mandanten ausgeführt; sie sind durch Tests gegen eine simulierte Graph-API abgedeckt.
- Die Anmeldung mit Microsoft und Single Sign-on (SSO) sind geplant: Der Code für die Microsoft-Anmeldung existiert, aber die Verknüpfung von Konten fehlt, daher kann sich in 0.1.0 niemand mit Microsoft anmelden.
- Microsoft hat am 1. Oktober 2026 begonnen, Exchange Web Services (EWS) für Exchange Online abzuschalten, und entfernt sie am 1. April 2027 endgültig. Restow hat EWS nie genutzt und spricht mit Microsoft ausschließlich über Microsoft Graph.
- Das Archiv wird durch Mail-Import mit Archivierung und ab Business durch den Empfang von Exchange-Online-Journalberichten gefüllt. Archiv-Sync aus Microsoft 365 (Graph) und aus IMAP-Postfächern ist geplant und nicht Teil von 0.1.0. Die Archivsuche deckt Betreff, Adressen und den Nachrichtentext importierter Mail ab; Anhangsinhalte werden nicht durchsucht.
- Auf lokalen, NFS- und SMB-Zielen erzwingt die Anwendung die Unveränderbarkeit; auf S3 mit Object Lock sperrt 0.1.0 nur die Datensätze der Archivelemente, noch nicht den Nachrichteninhalt und die Backup-Daten.
- Der automatische Rollback des Updaters greift nur, solange die Datenbankmigrationen der neuen Version noch nicht gelaufen sind; danach hält er an und behält den Datenbank-Dump.
- Der Endpoint-Agent sichert Dateien unter Linux und macOS: noch kein Windows, kein mTLS, keine Dateisystem-Snapshots, keine Festplatten-Abbilder. Die Release-Prüfungen haben das Installationsskript des Agents nur in einem Linux-Container ausgeführt; der macOS-Agent wird ausgeliefert, sein Installer war aber nicht Teil der Release-Prüfungen. Die Erstinstallation vertraut dem Installationsskript, das die Instanz ausliefert: Vergleichen Sie den Fingerabdruck des Release-Schlüssels, den es ausgibt, mit dem veröffentlichten, SHA256:2LB7RPpIS0wqbcZ2NA8MjuQN7ZfFPqBX3CwrGFSu76o.
- PST- und OST-Import sowie PST- und MSG-Export sind geplant. Ein importiertes Postfach lässt sich in diesem Release noch nicht löschen, Kalender und Kontakte aus MSG werden nicht importiert.
- Beta: nicht als einzige Sicherung verwenden.
Verifizierung
Bevor eine Version veröffentlicht wird, prüft der Release-Smoke-Lauf für den vollständigen und den Community-Build auf amd64 und arm64 Neuinstallation, Health, Passkey-Anmeldung, IMAP-Backup und -Restore mit Hash-Vergleich, Journal-Empfang und Kettenprüfung, Standalone-Restore, Speicherziele, einen Image-Scan, Endpoint-Backup und -Restore sowie Mail-Import und -Export (der Community-Build überspringt die Journal- und die Speicherziel-Prüfung, die die Business-Module oder einen zweiten Mandanten brauchen). Die Release-Notes auf GitHub enthalten das Ergebnis und sagen, was nicht gelaufen ist. Der abschließende Smoke-Lauf vom 1. Oktober 2026 hat für den vollständigen Build 9 von 11 Prüfungen vollständig bestanden, 1 teilweise (den Upgrade-Pfad, weil es kein früheres Release gibt) und 1 übersprungen: die Microsoft-365-Prüfung gegen einen Test-Tenant, mangels Zugangsdaten. Für den Community-Build hat er 7 vollständig und 1 teilweise bestanden (derselbe Upgrade-Pfad) und 3 übersprungen: die Microsoft-365-Prüfung und planmäßig die Journal-Prüfung und die Prüfung der Speicherziele, die im vollständigen Build laufen.