benbjohnson/litestream · error
abs: cannot delete ltx file %q: %w
Error message
abs: cannot delete ltx file %q: %w
What it means
This error is returned by ReplicaClient.DeleteLTXFiles when an LTX blob deletion fails in Azure Blob Storage. Before wrapping, BlobAlreadyExists-style 'not found' responses are filtered out via isNotExists(err), so reaching this error means the DELETE API call failed for a non-404 reason (auth, network, lease, permissions). The original Azure SDK error is wrapped with the blob key for diagnosis.
Source
Thrown at abs/replica_client.go:307
return resp.Body, nil
}
// DeleteLTXFiles deletes LTX files.
func (c *ReplicaClient) DeleteLTXFiles(ctx context.Context, a []*ltx.FileInfo) error {
if err := c.Init(ctx); err != nil {
return err
}
for _, info := range a {
key := litestream.LTXFilePath(c.Path, info.Level, info.MinTXID, info.MaxTXID)
c.logger.Debug("deleting ltx file", "level", info.Level, "minTXID", info.MinTXID, "maxTXID", info.MaxTXID, "key", key)
_, err := c.client.DeleteBlob(ctx, c.Bucket, key, nil)
if isNotExists(err) {
continue
} else if err != nil {
return fmt.Errorf("abs: cannot delete ltx file %q: %w", key, err)
}
internal.OperationTotalCounterVec.WithLabelValues(ReplicaClientType, "DELETE").Inc()
}
return nil
}
// DeleteAll deletes all LTX files.
func (c *ReplicaClient) DeleteAll(ctx context.Context) error {
if err := c.Init(ctx); err != nil {
return err
}
// List all blobs with the configured path prefix
prefix := "/"
if c.Path != "" {
prefix = strings.TrimSuffix(c.Path, "/") + "/"View on GitHub (pinned to 4ed7a308f6)
Solutions
- Check that the storage account/container credentials allow delete (Storage Blob Data Contributor role, or SAS with 'd' permission) — inspect the wrapped azblob error message for the actual HTTP status
- Verify no immutability policy, legal hold, or active lease on the blob in the Azure portal
- Test connectivity to the storage account (endpoint, DNS, firewall rules) and retry — transient failures are safe to re-run since DeleteLTXFiles skips already-missing blobs
- If the blob is soft-deleted and unresolvable, use 'litestream reset <db>' to clear local state, or delete the blob explicitly in the portal
Example fix
// before
_, err := c.client.DeleteBlob(ctx, c.Bucket, key, nil) // account lacks delete permission
// after
// fix credentials/SAS, then retry:
err := client.DeleteLTXFiles(ctx, fileInfos)
if err != nil {
if errors.Is(err, azureblob.ErrNoDeletePermission) { /* grant Storage Blob Data Contributor */ }
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// Go
func canDelete(ctx context.Context, c *abs.ReplicaClient) error {
_, err := c.client.DeleteBlob(ctx, c.Bucket, "__perm_probe__", nil) // expect NotExists, not 403
if err != nil && !isNotExists(err) { return err }
return nil
} Type guard
// Go
func isPermissionError(err error) bool {
var re *azcore.ResponseError
return errors.As(err, &re) && re.StatusCode == http.StatusForbidden
} Try / catch
if err := client.DeleteLTXFiles(ctx, infos); err != nil {
if isPermissionError(err) { /* fix credentials/role */ }
else if transient(err) { /* retry with backoff — idempotent */ }
return err
} Prevention
- Grant the identity Storage Blob Data Contributor (or SAS with delete permission)
- Avoid immutability policies/legal holds on replica containers
- Treat DeleteLTXFiles as retryable — it skips already-missing blobs
- Monitor the wrapped Azure error codes in logs to distinguish 403 vs 5xx vs network
When it happens
Trigger: Calling DeleteLTXFiles(ctx, fileInfos) while an azblob DeleteBlob call fails with a non-NotExists error — e.g. the container/account credentials lack delete permission, a lease is held on the blob, a SAS token lacks delete scope, the storage account is unavailable, or the context is cancelled mid-delete.
Common situations: Misconfigured connection string or SAS token without delete (d) permission; container-level immutable/lock policies on the storage account; network or DNS outage during retention cleanup; using a read-only account; blob soft-delete plus immutability policies blocking hard deletes.
Related errors
- abs: cannot delete blob %q: %w
- abs: cannot list blobs: %w
- oss: delete batch of %d objects: %w
- oss: failed to delete files:
- close iterator: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/33e17b8df943503c.
Report an issue: GitHub.