coollabsio/coolify · error · RuntimeException
The S3 storage used by an existing backup is unavailable.
Error message
The S3 storage used by an existing backup is unavailable.
What it means
Thrown while deleting a volume backup schedule: some executions have s3_uploaded=true and s3_storage_deleted=false, but executions->first()->s3 is null — the S3 storage configuration (S3Storage model) they reference was deleted from Coolify. The action aborts so remote objects in the bucket are not left untracked.
Source
Thrown at app/Actions/Shared/DeleteScheduledVolumeBackup.php:57
if ($localFilenames !== []) {
$server ??= $backup->server();
if (! $server) {
throw new \RuntimeException('The server is unavailable, so local backup archives cannot be deleted.');
}
deleteBackupsLocally($localFilenames, $server, throwError: true);
}
$s3Executions = $backup->executions()
->with('s3')
->where('s3_uploaded', true)
->where('s3_storage_deleted', false)
->get();
foreach ($s3Executions->groupBy('s3_storage_id') as $executions) {
$s3 = $executions->first()->s3;
if (! $s3) {
throw new \RuntimeException('The S3 storage used by an existing backup is unavailable.');
}
$filenames = $executions->pluck('filename')->filter()->all();
if ($filenames !== []) {
deleteBackupsS3($filenames, $s3);
}
}
$backup->delete();
} finally {
$lock->release();
}
}
}
View on GitHub (pinned to 70b9acc424)
Solutions
- Recreate an S3 storage entry with the same credentials/bucket so the action can delete the remote objects, then retry the schedule deletion.
- If the bucket is being abandoned, empty the relevant prefix manually in your provider console, then set s3_storage_deleted=true on those executions (or remove the execution rows) and delete the schedule.
- Going forward, delete backup schedules that target an S3 storage before deleting the storage itself.
Example fix
// before: deleting the schedule throws because the S3 storage is gone
DeleteScheduledVolumeBackup::run($backup);
// after: explicitly acknowledge the orphaned remote objects first
foreach ($backup->executions()->where('s3_uploaded', true)->where('s3_storage_deleted', false)->get() as $execution) {
if (is_null($execution->s3)) {
// objects already removed by hand (or bucket decommissioned)
$execution->update(['s3_storage_deleted' => true]);
}
}
DeleteScheduledVolumeBackup::run($backup); Defensive patterns
Strategy: validation
Validate before calling
// Fail fast if any S3-uploaded execution lost its storage config
$orphanedS3 = $backup->executions()
->with('s3')
->where('s3_uploaded', true)
->where('s3_storage_deleted', false)
->get()
->filter(fn ($e) => is_null($e->s3))
->isNotEmpty();
if ($orphanedS3) {
// recreate the S3 storage or acknowledge manual bucket cleanup first
} Type guard
function s3ExecutionsResolvable(\App\Models\ScheduledVolumeBackup $backup): bool
{
return $backup->executions()
->with('s3')
->where('s3_uploaded', true)
->where('s3_storage_deleted', false)
->get()
->every(fn ($e) => ! is_null($e->s3));
} Try / catch
try {
DeleteScheduledVolumeBackup::run($backup);
} catch (\RuntimeException $e) {
if (str_contains($e->getMessage(), 'S3 storage')) {
report('Schedule '.$backup->id.' references a deleted S3 storage; recreate it or clean the bucket manually.');
return;
}
throw $e;
} Prevention
- Delete backup schedules that upload to an S3 storage before deleting the storage entry itself.
- Keep a 'decommission' runbook for S3 storages: empty the prefix, then remove configs and schedules.
- Periodically audit for orphaned references: executions where s3_storage_id no longer resolves.
When it happens
Trigger: Deleting an S3 storage entry in Settings -> S3 Storage before deleting the backup schedules/executions that uploaded to it; groupBy('s3_storage_id') finds executions whose s3 relation no longer exists.
Common situations: Rotating S3 providers: user removes the old storage config assuming backups are independent; cleanup scripts delete storages but not dependent schedules; team membership changes hide the storage while executions still point at its id.
Related errors
- The server is unavailable, so local backup archives cannot b
- Wait for the running storage backup and recovery operations
- Server not found?!
- Database not found?!
- The selected S3 storage no longer exists. S3 backup has been
AI-assisted analysis of coollabsio/coolify@70b9acc424 (2026-08-17).
Data as JSON: /api/errors/a8321892dae3c331.
Report an issue: GitHub.