{"record":{"id":"81a4afdbe576fd3b","repo":"benbjohnson/litestream","slug":"oss-failed-to-delete-files","errorCode":null,"errorMessage":"oss: failed to delete files:","messagePattern":"oss: failed to delete files:","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"oss/replica_client.go","lineNumber":725,"sourceCode":"\t\tif obj.Key == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif _, ok := deleted[*obj.Key]; !ok {\n\t\t\tfailed = append(failed, *obj.Key)\n\t\t}\n\t}\n\n\tif len(failed) == 0 {\n\t\treturn nil\n\t}\n\n\t// Build error message listing failed keys\n\tvar b strings.Builder\n\tb.WriteString(\"oss: failed to delete files:\")\n\tfor _, key := range failed {\n\t\tfmt.Fprintf(&b, \"\\n%s\", key)\n\t}\n\treturn errors.New(b.String())\n}\n","sourceCodeStart":707,"sourceCodeEnd":727,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/oss/replica_client.go#L707-L727","documentation":"The Azure Blob (oss) replica client aggregates per-key failures from a batched delete into a single error listing every key that could not be deleted, prefixed with 'oss: failed to delete files:'. DeleteLTXFiles, DeleteAll and internal callers raise it when the multi-delete API reports errors for individual objects.","triggerScenarios":"Calling DeleteLTXFiles or DeleteAll on an oss/azure-backed replica where the batch delete API returns per-key errors (missing objects, permission failures, throttling) — deleteResultError builds the message from the failed key list.","commonSituations":"Retaining/purging old LTX files whose blobs were already removed by an Azure lifecycle policy; SAS token or account key lacking delete permission on the container; transient 429/5xx responses during bulk cleanup.","solutions":["Read the individual keys listed under the error header to identify which blobs failed and why","Verify the configured credentials (SAS token or shared key) grant delete (and list) permission on the container","Check whether an Azure storage lifecycle rule deleted the blobs already and adjust retention so litestream does not double-delete","Retry the delete; transient throttling is a common cause of partial batch failures"],"exampleFix":"// before\nif err := replica.DeleteAll(ctx); err != nil {\n    return err\n}\n// after\nif err := replica.DeleteAll(ctx); err != nil {\n    if strings.Contains(err.Error(), \"oss: failed to delete files:\") {\n        log.Printf(\"partial delete failure; check listed keys and container permissions: %v\", err)\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"// pre-check delete permission with a harmless probe\n_, err := client.TestPermission(ctx, container, \".litestream-delete-probe\")","typeGuard":"func isOSSBatchDeleteErr(err error) bool {\n    return strings.Contains(err.Error(), \"oss: failed to delete files:\")\n}","tryCatchPattern":"if err := replicaClient.DeleteAll(ctx); err != nil {\n    if isOSSBatchDeleteErr(err) {\n        // parse listed keys, verify container permissions, retry transient ones\n        log.Printf(\"partial batch delete: %v\", err)\n    }\n    return err\n}","preventionTips":["Grant the SAS/shared-key delete permission on the container","Align Azure lifecycle policies with litestream retention to avoid double-deletes","Back off and retry batch deletes on throttling","Log the failed key list from the error for follow-up"],"tags":["azure","blob-storage","delete","batch-delete"],"backgroundTag":"batch-delete-failed","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}