{"record":{"id":"da413fa129b9fc1a","repo":"coollabsio/coolify","slug":"the-selected-s3-storage-no-longer-exists-s3-backu","errorCode":null,"errorMessage":"The selected S3 storage no longer exists. S3 backup has been disabled.","messagePattern":"The selected S3 storage no longer exists\\. S3 backup has been disabled\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"app/Jobs/VolumeBackupJob.php","lineNumber":310,"sourceCode":"        try {\n            VolumeBackupRecoveryJob::recover($execution);\n\n            return '';\n        } catch (Throwable $exception) {\n            VolumeBackupRecoveryJob::dispatch($execution);\n\n            return ' Container recovery failed: '.$exception->getMessage();\n        }\n    }\n\n    private function uploadToS3(string $backupLocation, string $backupDirectory, Server $server): void\n    {\n        $s3 = $this->backup->s3;\n\n        if (! $s3) {\n            $this->backup->update(['save_s3' => false, 's3_storage_id' => null]);\n\n            throw new \\RuntimeException('The selected S3 storage no longer exists. S3 backup has been disabled.');\n        }\n\n        $s3->testConnection(shouldSave: true);\n        $containerName = 'volume-upload-'.$this->execution->uuid;\n        $image = coolifyHelperImage().':'.getHelperVersion();\n        $resolveOptions = collect(SafeWebhookUrl::minioClientResolveOptions($s3->endpoint, $s3->trustedInternalHosts()))\n            ->map(fn (string $option): string => '--resolve '.escapeshellarg($option))\n            ->implode(' ');\n        $resolveOptions = $resolveOptions === '' ? '' : ' '.$resolveOptions;\n\n        try {\n            instant_remote_process([\n                'docker rm -f '.escapeshellarg($containerName).' >/dev/null 2>&1 || true',\n                'docker run -d --name '.escapeshellarg($containerName).' --rm -v '\n                    .escapeshellarg($backupLocation.':'.$backupLocation.':ro').' '.escapeshellarg($image),\n                'docker exec '.escapeshellarg($containerName).' mc alias set'.$resolveOptions.' temporary '\n                    .escapeshellarg($s3->endpoint).' '.escapeshellarg($s3->key).' '.escapeshellarg($s3->secret),\n                'docker exec '.escapeshellarg($containerName).' mc cp '.escapeshellarg($backupLocation).' '","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Jobs/VolumeBackupJob.php#L292-L328","documentation":"uploadToS3() loads the S3 storage referenced by the volume backup's s3_storage_id. When the relation resolves to null (the S3 storage row was deleted after the schedule was created), the job flips save_s3 off on the backup, clears s3_storage_id, and throws so the execution is marked failed instead of silently skipping the upload.","triggerScenarios":"A scheduled volume backup has save_s3 = true and an s3_storage_id whose S3 storage row no longer exists; on the next run `$this->backup->s3` is null.","commonSituations":"Deleting an S3 storage definition in Settings > S3 Storage without reassigning or deleting the scheduled backups that reference it.","solutions":["Edit the volume backup schedule, select a valid S3 storage, and re-enable 'Save to S3' - the job auto-disabled both when it threw","Re-create the S3 storage if it was removed by mistake, then relink the schedule","Before deleting an S3 storage in the future, reassign or remove schedules that point at it"],"exampleFix":"// before - detected only at backup time\n$s3 = $this->backup->s3;\nif (! $s3) {\n    throw new \\RuntimeException('The selected S3 storage no longer exists. S3 backup has been disabled.');\n}\n// after - reject stale references when the schedule is saved\n$validated = $request->validate([\n    's3_storage_id' => ['nullable', Rule::exists('s3_storages', 'id')],\n]);","handlingStrategy":"validation","validationCode":"use Illuminate\\Validation\\Rule;\n\n// when saving the scheduled volume backup\n$data = $request->validate([\n    's3_storage_id' => ['nullable', Rule::exists('s3_storages', 'id')],\n]);","typeGuard":"function backupHasValidS3($backup): bool\n{\n    return $backup->s3_storage_id === null || $backup->s3()->exists();\n}","tryCatchPattern":null,"preventionTips":["Reassign or delete scheduled backups before removing an S3 storage","Treat a silently disabled 'Save to S3' flag as a signal to audit backup schedules","Show a warning in the UI listing schedules that reference an S3 storage about to be deleted"],"tags":["backup","s3","dangling-reference","scheduled-task"],"backgroundTag":"dangling-foreign-key-reference","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}