> ## Documentation Index
> Fetch the complete documentation index at: https://docs.baseten.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Sync volumes from remote sources

> Copy a Hugging Face repository, an object storage prefix, or a Baseten Training checkpoint into a BDN volume as a new version.

`baseten volume sync` copies a remote source into a volume as a new sealed version. The sync runs as a durable background job on Baseten, so nothing downloads to your machine.

## Start a sync

Pass the source URI with `--source` and the destination volume with `--dest`. A tag on `--dest` tags the version the sync publishes:

```sh theme={"system"}
baseten volume sync start \
  --source hf://<organization>/<repository> \
  --dest bdn:<namespace>/<volume>:hf \
  --wait
```

The source's URI scheme selects the provider:

| Scheme | Source |
| - | - |
| `hf://` | Hugging Face repository |
| `s3://` | Amazon S3 |
| `gs://` | Google Cloud Storage |
| `azure://` | Azure Blob Storage |
| `r2://` | Cloudflare R2 |
| `cw://` | CoreWeave AI Object Storage |
| `bt://` | [Baseten Training](/development/model/bdn#baseten-training) checkpoint |

Repeat `--include` and `--exclude` with glob patterns to filter source-relative paths:

```sh theme={"system"}
baseten volume sync start \
  --source hf://<organization>/<repository> \
  --dest bdn:<namespace>/<volume> \
  --include "*.safetensors" --include "*.json"
```

Without `--wait`, the command returns as soon as Baseten creates the job and prints its sync ID. With `--wait`, it follows the job until it's `READY`, `FAILED`, or `CANCELED`, writes progress to stderr, and prints the result, including the new version's reference, to stdout. Pressing Ctrl+C stops waiting without cancelling the sync, and prints the commands to check or cancel it.

## Check a sync

Check the status of a sync using the ID returned when you started it:

```sh theme={"system"}
baseten volume sync describe --sync-id <sync-id>
```

A `READY` sync includes the reference of the version it published, and a `FAILED` sync includes an error code and message.

## List syncs

List syncs for a destination volume:

```sh theme={"system"}
baseten volume sync list --dest bdn:<namespace>/<volume>
```

The command shows syncs newest first. `--dest` matches one exact destination reference.

## Cancel a sync

Cancel a sync using its ID:

```sh theme={"system"}
baseten volume sync cancel --sync-id <sync-id>
```

Cancelling a sync that already finished returns it unchanged and doesn't delete a version it published.

## Fix a failed sync

When the source rejects a sync, Baseten stops the job instead of retrying it and reports one of these error codes. The message names the source URI and, when the provider returned one, its error code, such as `NoSuchBucket` or `HTTP_404`.

| Code | Cause | Fix |
| - | - | - |
| `SOURCE_NOT_FOUND` | The bucket, container, repository, revision, or file doesn't exist, or your credentials can't see it. | Check the source URI and revision. |
| `SOURCE_ACCESS_DENIED` | The source refused your credentials. | Check that the source exists and that the secret, OIDC role, or AssumeRole role grants read access. |
| `SOURCE_INVALID` | The source URI, credentials, or provider settings are malformed. | Check the source URI, credentials, and provider settings. A `PermanentRedirect` provider code means the bucket is in a different region or behind a different endpoint. |
| `SOURCE_CHANGED` | A file changed or disappeared after the sync listed the source. | Start a new sync to read a fresh snapshot. |

Any other failure reports `SYNC_FAILED`. Baseten retries transient errors, such as throttling and timeouts, before it fails a sync.

## Authenticate with a secret

Public sources need no credentials. For a private source, store its credentials as a Baseten [secret](/development/model/secrets) in the same team, and pass the secret's name with `--auth-secret-name`:

```sh theme={"system"}
baseten volume sync start \
  --source s3://<bucket>/<prefix> \
  --dest bdn:<namespace>/<volume> \
  --auth-secret-name <secret-name> \
  --wait
```

The secret's value depends on the source:

| Source | Secret value |
| - | - |
| Hugging Face | Your Hugging Face access token. |
| Amazon S3, CoreWeave | JSON with `aws_access_key_id`, `aws_secret_access_key`, and `aws_region`, plus `aws_session_token` for temporary credentials. |
| Cloudflare R2 | JSON with `aws_access_key_id` and `aws_secret_access_key`. |
| Google Cloud Storage | A service account JSON key. |
| Azure Blob Storage | JSON with `account_key`. The account name comes from the source URI. |

These are the same formats that [`weights`](/development/model/bdn#source-types-and-authentication) sources use. Baseten Training sources authenticate automatically.

## Authenticate with OIDC or AWS AssumeRole

For S3 and GCS, you can grant access with short-lived credentials instead of a stored secret. Pass the flags for one method; a sync accepts only one authentication method.

Volume sync uses its own OIDC workload identity, so a trust policy written for model or training workloads doesn't cover it. Before your first OIDC sync, set up the AWS OIDC provider or GCP workload identity provider, then scope its trust policy to volume sync, as described in [Volume sync](/organization/oidc#volume-sync-only) in the OIDC guide. Grant the role or service account read access to the source bucket and prefix.

**Amazon S3 with AWS OIDC**:

```sh theme={"system"}
baseten volume sync start \
  --source s3://<bucket>/<prefix> \
  --dest bdn:<namespace>/<volume> \
  --auth-aws-oidc-role-arn arn:aws:iam::<aws-account-id>:role/<role-name> \
  --auth-aws-oidc-region <region> \
  --wait
```

**Google Cloud Storage with GCP OIDC**:

```sh theme={"system"}
baseten volume sync start \
  --source gs://<bucket>/<prefix> \
  --dest bdn:<namespace>/<volume> \
  --auth-gcp-oidc-service-account <service-account-email> \
  --auth-gcp-oidc-workload-identity-provider projects/<project-number>/locations/global/workloadIdentityPools/<pool>/providers/<provider> \
  --wait
```

**Amazon S3 with AWS AssumeRole**: pass `--auth-aws-assume-role-arn` and `--auth-aws-assume-role-region`. See [AWS AssumeRole](/organization/aws-assume-role) to set up the role.

For every flag, see [`baseten volume sync`](/reference/cli/baseten/volume-sync).
