Skip to main content

Overview

The cloudstic break-lock command forcibly removes lock files from a Cloudstic repository. Locks are automatically acquired by operations like backup, prune, and forget to prevent concurrent writes that could corrupt the repository.
Only use break-lock if you are certain no other Cloudstic process is currently running. Breaking a lock held by an active process can cause repository corruption or data loss.

When to Use

Use break-lock when:
  • A Cloudstic process was killed (SIGKILL, crash, system reboot) and left a stale lock
  • You receive an error like: repository is locked by another operation
  • You have verified that no other Cloudstic process is running (check with ps, htop, or your process manager)
Locks automatically expire after a timeout period (typically 1 hour). If possible, wait for the lock to expire naturally instead of breaking it.

Basic Usage

cloudstic break-lock [options]

Terminal Output Examples

Stale Lock Removed

$ cloudstic break-lock
Locks removed:
  Operation:  backup
  Holder:     hostname-12345-20260301T103045Z
  Acquired:   2026-03-01T10:30:45Z
  Expired at: 2026-03-01T11:30:45Z
  Shared:     false
This indicates a backup operation’s lock was successfully removed. The lock was acquired on March 1 at 10:30 and would have expired at 11:30.

No Lock Found

$ cloudstic break-lock
No lock found repository is not locked.
The repository is not currently locked. No action was taken.

Multiple Locks Removed

$ cloudstic break-lock
Locks removed:
  Operation:  backup
  Holder:     server1-67890-20260301T093000Z
  Acquired:   2026-03-01T09:30:00Z
  Expired at: 2026-03-01T10:30:00Z
  Shared:     false

  Operation:  prune
  Holder:     server2-11223-20260301T095000Z
  Acquired:   2026-03-01T09:50:00Z
  Expired at: 2026-03-01T10:50:00Z
  Shared:     false
Multiple stale locks from different processes were removed.

Command Flags

break-lock has no command-specific flags. It uses global flags for repository access.

Global Flags

-store
string
default:"local"
Storage backend type: local, b2, s3, sftp.
-store-path
string
default:"./backup_store"
Local/SFTP directory path or B2/S3 bucket name.
-store-prefix
string
default:""
Key prefix for B2/S3 objects.
-encryption-key
string
default:""
Platform key (64 hex chars = 32 bytes) for encrypted repositories.
-encryption-password
string
default:""
Repository password for encrypted repositories.
-recovery-key
string
default:""
24-word BIP39 recovery phrase.
-kms-key-arn
string
default:""
AWS KMS key ARN for KMS-encrypted repositories.
-verbose
boolean
default:"false"
Log detailed operations.
-quiet
boolean
default:"false"
Suppress output (not recommended for this command).
-debug
boolean
default:"false"
Log every store request (network calls, timing, sizes).

S3-Specific Flags

-s3-endpoint
string
default:""
S3-compatible endpoint (MinIO, R2, etc.).
-s3-region
string
default:"us-east-1"
S3 region.
-s3-access-key
string
default:""
S3 access key ID.
-s3-secret-key
string
default:""
S3 secret access key.

SFTP-Specific Flags

-sftp-host
string
default:""
SFTP server hostname.
-sftp-port
string
default:"22"
SFTP server port.
-sftp-user
string
default:""
SFTP username.
-sftp-password
string
default:""
SFTP password.
-sftp-key
string
default:""
Path to SSH private key file.

Examples

Local Repository

cloudstic break-lock

Remote S3 Repository

export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

cloudstic break-lock \
  -store s3 \
  -store-path my-backup-bucket \
  -s3-region us-west-2 \
  -encryption-password "my-passphrase"

SFTP Repository

cloudstic break-lock \
  -store sftp \
  -sftp-host backup.example.com \
  -sftp-user backupuser \
  -sftp-key ~/.ssh/id_rsa \
  -store-path /home/backupuser/cloudstic

With Debug Logging

cloudstic break-lock -debug
Output:
[DEBUG] GET lock/backup-server1-12345.lock (234 bytes, 45ms)
[DEBUG] DELETE lock/backup-server1-12345.lock (0 bytes, 32ms)
Locks removed:
  Operation:  backup
  Holder:     server1-12345-20260301T103045Z
  Acquired:   2026-03-01T10:30:45Z
  Expired at: 2026-03-01T11:30:45Z
  Shared:     false

How Locks Work

Lock Acquisition

When a Cloudstic operation starts, it attempts to acquire a lock:
  1. Generate lock ID: <operation>-<hostname>-<pid>-<timestamp>
  2. Write lock file: Store lock metadata (holder, operation, acquired time, expiration)
  3. Validate lock: Check that no other exclusive lock exists
  4. Proceed with operation
Some operations use shared locks (e.g., check, restore) that allow concurrent reads. Others use exclusive locks (e.g., backup, prune) to prevent concurrent writes.

Lock Expiration

Locks have a default expiration time (typically 1 hour). If a lock is older than its expiration time:
  • Automatic expiration: New operations can proceed and ignore expired locks
  • Manual cleanup: break-lock removes expired or stale locks

Lock Storage

Locks are stored as objects in the repository:
  • Key format: lock/<operation>-<holder>.lock
  • Content: JSON metadata (operation, holder, timestamps, shared flag)
  • Unencrypted: Lock files are stored in plaintext for debuggability

Understanding Lock Information

Operation

The Cloudstic command that held the lock:
  • backup — Backup operation
  • prune — Prune operation
  • forget — Forget operation
  • init — Repository initialization (rare, short-lived)

Holder

Unique identifier for the process that acquired the lock:
hostname-12345-20260301T103045Z
  • hostname: Machine hostname
  • 12345: Process ID (PID)
  • timestamp: When the lock was acquired (ISO 8601 UTC)

Acquired / Expired At

  • Acquired: When the lock was first created
  • Expired at: When the lock would automatically become invalid
If the current time is past “Expired at”, the lock is already stale and safe to break.

Shared

  • true: Shared lock (allows concurrent read operations)
  • false: Exclusive lock (prevents all other operations)

Safety Considerations

Breaking an active lock can corrupt your repository. Always verify no Cloudstic process is running before using break-lock.

How to Verify No Active Processes

Linux/macOS

# Check for cloudstic processes
ps aux | grep cloudstic

# Or use pgrep
pgrep -fl cloudstic

# Check system-wide
htop  # Search for "cloudstic"

Windows

# PowerShell
Get-Process | Where-Object { $_.ProcessName -like "*cloudstic*" }

# Task Manager
# Look for "cloudstic.exe" in Processes tab

Systemd/Cron

Check if Cloudstic is running as a scheduled task:
# Systemd timers
systemctl list-timers --all | grep cloudstic

# Cron jobs
crontab -l | grep cloudstic
sudo crontab -l | grep cloudstic  # System-wide cron

When It’s Safe to Break a Lock

Safe scenarios:
  • Process was killed (SIGKILL, crash, reboot)
  • Lock expiration time has passed
  • You confirmed no active Cloudstic processes
  • Lock holder hostname is a decommissioned machine
Unsafe scenarios:
  • Active backup is in progress on another machine
  • Scheduled backup might be running (check cron/systemd)
  • Uncertain about process status

Troubleshooting

Error: Failed to init store

Failed to init store: no such host
Cause: Cannot connect to storage backend. Resolution: Verify -store, -store-path, and credentials (e.g., -s3-access-key, -sftp-host).

Error: Failed to break lock

Failed to break lock: permission denied
Cause: Insufficient permissions to delete lock objects. Resolution:
  • Check storage backend permissions (S3 IAM policy, SFTP file permissions)
  • Verify you have write access to the repository

Lock reappears immediately after breaking

Cause: Another process is actively creating locks (e.g., running backup). Resolution:
  1. Find and stop the active process
  2. Wait for the lock to expire naturally (check “Expired at” time)
  3. Do not repeatedly break locks — this indicates an underlying issue

Repository is corrupted after breaking lock

Cause: Lock was broken while another process was writing. Resolution:
  1. Run cloudstic check to assess damage
  2. If errors found, restore from an earlier snapshot or backup
  3. In the future, always verify no processes are running before breaking locks

Use Cases

Crashed Backup Job

# Backup process was killed by system OOM killer
$ cloudstic backup -source local -source-path /data
Killed

# Later, trying to run backup again:
$ cloudstic backup -source local -source-path /data
Error: repository is locked by another operation

# Verify no processes running:
$ ps aux | grep cloudstic
# (no results)

# Break the stale lock:
$ cloudstic break-lock
Locks removed:
  Operation:  backup
  Holder:     server1-12345-20260301T103045Z
  ...

# Retry backup:
$ cloudstic backup -source local -source-path /data
# Success!

Remote Repository Lock After Server Reboot

# Server rebooted unexpectedly while backup was running
# Next backup attempt:
$ cloudstic backup -store s3 -store-path my-bucket -source local -source-path /data
Error: repository is locked by another operation

# Check lock details:
$ cloudstic break-lock -store s3 -store-path my-bucket
Locks removed:
  Operation:  backup
  Holder:     old-server-78901-20260228T153000Z
  Acquired:   2026-02-28T15:30:00Z
  Expired at: 2026-02-28T16:30:00Z  # Already expired!
  Shared:     false

# Lock was already expired — safe to remove

CI/CD Pipeline Failure

# CI job was canceled mid-backup
# Next CI run:
- cloudstic backup -source local -source-path /workspace
  Error: repository is locked by another operation

# CI script includes lock recovery:
- cloudstic break-lock || true  # Ignore errors if no lock
- cloudstic backup -source local -source-path /workspace
For automated environments (CI/CD, cron), consider adding break-lock to your recovery logic. However, ensure jobs don’t run concurrently (e.g., use job queues or single-instance constraints).

Exit Codes

  • 0 — Success (lock removed or no lock found)
  • 1 — Error (store initialization failed, permission denied, or command error)