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

# Troubleshooting

> Common issues and solutions for Basecut CLI and agents

This guide covers common issues you may encounter when using Basecut, along with their solutions and debugging techniques.

## Database Connection Issues

### Connection Refused

**Symptoms:**

```
✗ Error: failed to connect to database
  dial tcp: connection refused
```

**Solutions:**

1. **Verify database is running:**

   ```bash theme={null}
   pg_isready -h localhost -p 5432
   ```

2. **Check connection string format:**

   ```bash theme={null}
   # Correct format
   postgresql://user:password@host:5432/database

   # Common mistakes
   postgresql://host:5432  # Missing database name
   postgresql://user@host  # Missing port
   ```

3. **Test connectivity:**

   ```bash theme={null}
   psql "$BASECUT_DATABASE_URL" -c "SELECT 1"
   ```

4. **Check firewall rules:**
   * Ensure port 5432 is open
   * For self-hosted agents, verify network security groups allow outbound connections

***

### Host Not Found

**Symptoms:**

```
✗ Error: failed to connect to database
  dial tcp: lookup prod-db.internal: no such host
```

**Solutions:**

1. **Verify hostname resolves:**

   ```bash theme={null}
   nslookup prod-db.internal
   dig prod-db.internal
   ```

2. **Use IP address instead:**

   ```bash theme={null}
   postgresql://user:pass@10.0.1.100:5432/myapp
   ```

3. **For private databases without public access:**
   * Use local execution (default) instead of agent execution
   * Or deploy self-hosted agents in the same VPC

***

### Permission Denied

**Symptoms:**

```
✗ Error: permission denied for schema public
✗ Error: must be owner of table users
```

**Solutions:**

1. **Grant SELECT permissions:**

   ```sql theme={null}
   GRANT USAGE ON SCHEMA public TO basecut_user;
   GRANT SELECT ON ALL TABLES IN SCHEMA public TO basecut_user;

   -- For future tables
   ALTER DEFAULT PRIVILEGES IN SCHEMA public
     GRANT SELECT ON TABLES TO basecut_user;
   ```

2. **Verify user permissions:**

   ```sql theme={null}
   -- Check what schemas user can access
   SELECT schema_name
   FROM information_schema.schemata
   WHERE schema_name NOT LIKE 'pg_%' AND schema_name != 'information_schema';

   -- Check table permissions
   SELECT table_schema, table_name, privilege_type
   FROM information_schema.table_privileges
   WHERE grantee = 'basecut_user';
   ```

***

### SSL/TLS Connection Errors

**Symptoms:**

```
✗ Error: SSL is not enabled on the server
✗ Error: certificate verify failed
```

**Solutions:**

1. **For databases requiring SSL:**

   ```bash theme={null}
   postgresql://user:pass@host:5432/db?sslmode=require
   ```

2. **For self-signed certificates:**

   ```bash theme={null}
   postgresql://user:pass@host:5432/db?sslmode=require&sslrootcert=/path/to/ca.crt
   ```

3. **Disable SSL verification (dev only, not recommended for production):**
   ```bash theme={null}
   postgresql://user:pass@host:5432/db?sslmode=disable
   ```

***

## Authentication Failures

### Invalid API Key

**Symptoms:**

```
✗ Error: Unauthorized: invalid API key
✗ Error: API key is invalid or expired
```

**Solutions:**

1. **Verify API key is set:**

   ```bash theme={null}
   echo $BASECUT_API_KEY
   ```

2. **Re-authenticate:**

   ```bash theme={null}
   basecut login
   ```

3. **Check API key format:**
   * Live keys: `bc_live_*`
   * Test keys: `bc_test_*`
   * Ensure no extra spaces or newlines

4. **For CI/CD, verify secret is correctly set:**

   ```bash theme={null}
   # GitHub Actions
   echo "${{ secrets.BASECUT_API_KEY }}" | wc -c  # Should be > 50

   # GitLab CI
   echo "$BASECUT_API_KEY" | wc -c
   ```

5. **Check API key in dashboard:**
   * Login to [basecut.dev](https://basecut.dev)
   * Navigate to Settings → API Keys
   * Verify key hasn't been revoked

***

### whoami Command Fails

**Symptoms:**

```bash theme={null}
$ basecut whoami
not authenticated
```

**Solutions:**

1. **Login again:**

   ```bash theme={null}
   basecut login
   ```

2. **Check credentials file:**

   ```bash theme={null}
   cat ~/.basecut/credentials
   # Should contain API key
   ```

3. **Use the profile you logged into:**
   ```bash theme={null}
   basecut whoami --profile staging
   ```

***

## Snapshot Creation Issues

### Extraction Limits Reached

**Symptoms:**

```
⚠ Warning: per_table limit (1000) reached for table 'users'
⚠ Warning: total row limit (50000) reached
✓ Snapshot created with partial data
```

**Solutions:**

1. **Increase limits in basecut.yml:**

   ```yaml theme={null}
   limits:
     rows:
       per_table: 5000 # Increase per-table limit
       total: 200000 # Increase total budget
   ```

2. **Add more specific WHERE clauses:**

   ```yaml theme={null}
   from:
     - table: users
       where: 'created_at > :since AND status = :status'
       params:
         since: '2024-01-01'
         status: 'active' # More specific filter
   ```

3. **Use table-specific limits:**
   ```yaml theme={null}
   limits:
     rows:
       per_table: 1000
       tables:
         public.audit_logs: 100 # Limit noisy tables
         public.sessions: 0 # Unlimited for this table (use `exclude` to skip)
   ```

***

### Foreign Key Constraint Violations

**Symptoms:**

```
✗ Error: foreign key constraint violation
  Table 'orders' references missing row in 'users'
```

**Solutions:**

1. **This shouldn't happen!** Basecut automatically ensures referential integrity. If you see this:
   * File a bug report at [github.com/basecuthq/basecut/issues](https://github.com/basecuthq/basecut/issues)
   * Include your `basecut.yml` configuration
   * Include the error message and stack trace

2. **Workaround - increase upstream depth:**
   ```yaml theme={null}
   traverse:
     parents: 15 # Follow parent relationships further
     children: 10
   ```

***

### Timeout on Large Extractions

**Symptoms:**

```
✗ Error: context deadline exceeded
✗ Error: operation timed out after 300s
```

**Solutions:**

1. **Use self-hosted agents instead of local execution:**

   ```bash theme={null}
   # Instead of local execution (default)
   basecut snapshot create --config basecut.yml

   # Use agent execution for large datasets
   basecut snapshot create --config basecut.yml --async
   ```

2. **Reduce snapshot scope:**

   ```yaml theme={null}
   limits:
     rows:
       per_table: 1000 # Start smaller
   ```

3. **Use sampling:**
   ```yaml theme={null}
   sampling:
     mode: 'first' # Faster than 'random'
   ```

***

## Snapshot Restore Issues

### Schema Validation Failures

**Symptoms:**

```
✗ Error: schema mismatch: table 'users' missing column 'email_verified'
✗ Error: snapshot schema version incompatible with target database
```

**Solutions:**

1. **Run migrations first:**

   ```bash theme={null}
   # Run migrations to match snapshot schema
   npm run migrate

   # Then restore
   basecut snapshot restore dev-seed:latest --target "$BASECUT_DATABASE_URL"
   ```

2. **Force restore (skip validation):**

   ```bash theme={null}
   basecut snapshot restore dev-seed:latest --target "$BASECUT_DATABASE_URL" --force
   ```

   <Warning>
     Only use `--force` if you understand the schema differences. Missing
     columns or type changes can still fail during insert.
   </Warning>

3. **Inspect the exact snapshot reference you're restoring:**
   ```bash theme={null}
   basecut snapshot inspect dev-seed:latest --json
   ```

***

### Duplicate Key Violations

**Symptoms:**

```
✗ Error: duplicate key value violates unique constraint "users_pkey"
  Key (id)=(123) already exists
```

**Solutions:**

1. **Use --reset flag to truncate tables first:**

   ```bash theme={null}
   basecut snapshot restore dev-seed:latest \
     --target "$BASECUT_DATABASE_URL" \
     --reset
   ```

   <Warning>
     `--reset` is destructive. It truncates all tables included in the snapshot
     before restoring.
   </Warning>

2. **Manually truncate conflicting tables:**

   ```sql theme={null}
   TRUNCATE TABLE users, orders, line_items CASCADE;
   ```

3. **Restore to empty database:**

   ```bash theme={null}
   # Create fresh database
   createdb myapp_test

   # Restore snapshot
   basecut snapshot restore dev-seed:latest \
     --target "postgresql://localhost:5432/myapp_test"
   ```

***

### Foreign Key Cycle / Non-Deferrable Constraint Block

**Symptoms:**

```
✗ Error: Restore blocked: your database has foreign key constraints that cannot be satisfied during bulk insert.
```

This usually means your restore scope includes self-referential tables or FK cycles, and at least some of those constraints are `NOT DEFERRABLE`.

**Solutions:**

1. **Run FK preflight analysis first (recommended):**

   ```bash theme={null}
   basecut snapshot restore dev-seed:latest \
     --target "$BASECUT_DATABASE_URL" \
     --analyze-fks
   ```

   Use the output to identify blocking tables/constraints and whether nullable fallback is available.

2. **If nullable fallback is available, run restore normally:**

   Basecut will automatically use a two-phase strategy (`INSERT` with temporary `NULL`s, then backfill) for eligible nullable FK cycles.

3. **Make blocking FK constraints deferrable (recommended long-term):**

   ```sql theme={null}
   ALTER TABLE <schema>.<table>
   ALTER CONSTRAINT <constraint_name>
   DEFERRABLE INITIALLY DEFERRED;
   ```

4. **Use unsafe bypass only as a last resort:**

   ```bash theme={null}
   basecut snapshot restore dev-seed:latest \
     --target "$BASECUT_DATABASE_URL" \
     --unsafe-disable-fk-checks
   ```

   <Warning>
     `--unsafe-disable-fk-checks` disables FK enforcement during restore.
     Use only in controlled environments and validate integrity after restore.
   </Warning>

***

### Restore Too Slow

**Symptoms:**

* Restore takes several minutes for small snapshots
* Progress bar stuck at 0%

**Solutions:**

1. **Check database connectivity:**

   ```bash theme={null}
   ping -c 3 your-db-host
   ```

2. **Use local database for faster restore:**

   ```bash theme={null}
   # Instead of remote database
   basecut snapshot restore dev-seed:latest --target "postgresql://remote:5432/db"

   # Use local database
   basecut snapshot restore dev-seed:latest --target "postgresql://localhost:5432/db"
   ```

3. **Disable triggers during restore (advanced):**
   ```sql theme={null}
   ALTER TABLE users DISABLE TRIGGER ALL;
   -- Restore snapshot
   ALTER TABLE users ENABLE TRIGGER ALL;
   ```

***

## Storage Issues

### S3 Access Denied

**Symptoms:**

```
✗ Error: failed to upload snapshot
  AccessDenied: User does not have PutObject permission
```

**Solutions:**

1. **Verify AWS credentials:**

   ```bash theme={null}
   aws s3 ls s3://your-bucket/
   ```

2. **Check IAM policy** grants `s3:PutObject`, `s3:GetObject`, and `s3:ListBucket` on your bucket. See [Storage Providers](/core-concepts/storage-providers#required-permissions) for the full policy.

3. **Use correct credentials:**

   ```bash theme={null}
   export AWS_ACCESS_KEY_ID=your_key_id
   export AWS_SECRET_ACCESS_KEY=your_secret_key

   # Or use AWS CLI profile
   aws configure
   ```

***

### S3 Region/Endpoint Errors (Common with `--async`)

**Symptoms:**

```
✗ Error: failed to upload snapshot
  ... Invalid region ...
```

**Why this happens:**

* Local runs can succeed using your local AWS profile region
* `--async` runs execute on a self-hosted agent, which may not have the same region config

**Solutions:**

1. **Set region in `basecut.yml` for S3 output:**

   ```yaml theme={null}
   output:
     provider: s3
     bucket: your-bucket
     region: us-east-1
   ```

2. **For Cloudflare R2 / S3-compatible endpoints, set both endpoint and region:**

   ```yaml theme={null}
   output:
     provider: s3
     bucket: your-r2-bucket
     region: auto
     endpoint: https://<accountid>.r2.cloudflarestorage.com
   ```

3. **If you cannot set `output.region`, ensure `AWS_REGION` is set on the agent environment.**

***

### GCS Permission Errors

**Symptoms:**

```
✗ Error: failed to upload to GCS
  403: Forbidden
```

**Solutions:**

1. **Verify GCS credentials:**

   ```bash theme={null}
   gsutil ls gs://your-bucket/
   ```

2. **Check service account permissions:**

   ```bash theme={null}
   gcloud storage buckets add-iam-policy-binding gs://your-bucket \
     --member=serviceAccount:basecut@project.iam.gserviceaccount.com \
     --role=roles/storage.objectAdmin
   ```

3. **Use correct credentials:**

   ```bash theme={null}
   export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account-key.json

   # Or use gcloud auth
   gcloud auth application-default login
   ```

***

### Snapshot Not Found

**Symptoms:**

```
✗ Error: snapshot not found: dev-seed:latest
✗ Error: no versions found for snapshot 'dev-seed'
```

**Solutions:**

1. **List available snapshots:**

   ```bash theme={null}
   basecut snapshot list --name dev-seed
   ```

2. **Check snapshot name spelling:**

   ```bash theme={null}
   # Common mistake: wrong name
   basecut snapshot restore dev-seed:latest  # Wrong
   basecut snapshot restore dev-data:latest  # Correct
   ```

3. **Verify storage provider configuration:**
   ```yaml theme={null}
   # In basecut.yml
   output:
     provider: s3
     bucket: your-bucket # Ensure this matches where snapshot was created
     region: us-east-1
   ```

***

## Self-Hosted Agent Issues

### Agent Not Picking Up Jobs

**Symptoms:**

* Jobs submitted with `--async` never complete
* Agent logs show no activity

**Solutions:**

1. **Check agent logs:**

   ```bash theme={null}
   docker logs basecut-agent
   ```

2. **Verify API key format and org access:**

   ```bash theme={null}
   echo "$BASECUT_API_KEY" | grep -E '^bc_(live|test)_'
   ```

3. **Check network connectivity to Basecut API:**

   ```bash theme={null}
   docker exec basecut-agent curl https://api.basecut.dev/health
   ```

4. **Verify agent registration:**
   * Check dashboard for registered agents
   * Ensure agent is in "Active" state

***

### Agent Database Connection Failures

**Symptoms:**

```
Agent log: failed to connect to database
Agent log: dial tcp: i/o timeout
```

**Solutions:**

1. **Test database access from agent:**

   ```bash theme={null}
   docker exec basecut-agent psql "$BASECUT_DATABASE_URL" -c "SELECT 1"
   ```

2. **Check network security groups:**
   * Verify agent's security group allows outbound to database port
   * Verify database's security group allows inbound from agent

3. **Use private IP for database in same VPC:**

   ```bash theme={null}
   # Instead of public IP
   postgresql://user:pass@1.2.3.4:5432/db

   # Use private IP
   postgresql://user:pass@10.0.1.100:5432/db
   ```

***

## Performance Issues

### Slow Extractions

**Symptoms:**

* Snapshot creation takes hours
* "Extracting..." stuck at same table count

**Solutions:**

1. **Check database indexes:**

   ```sql theme={null}
   -- Ensure foreign key columns are indexed
   CREATE INDEX CONCURRENTLY idx_orders_user_id ON orders(user_id);
   CREATE INDEX CONCURRENTLY idx_line_items_order_id ON line_items(order_id);
   ```

2. **Use sampling instead of full extraction:**

   ```yaml theme={null}
   sampling:
     mode: 'first' # Much faster than 'random'
   ```

3. **Reduce traversal depth:**

   ```yaml theme={null}
   traverse:
     parents: 3 # Reduce from 10
     children: 5 # Reduce from 10
   ```

4. **Use agent execution for large datasets:**
   ```bash theme={null}
   basecut snapshot create --config basecut.yml --async
   ```

***

## Debugging Techniques

### Check Configuration Parsing

**Verify YAML syntax:**

```bash theme={null}
# Use a YAML validator
python -c "import yaml; yaml.safe_load(open('basecut.yml'))"
```

***

### Test Individual Components

**Test database connection:**

```bash theme={null}
psql "$BASECUT_DATABASE_URL" -c "SELECT current_database(), current_user;"
```

**Test storage access:**

```bash theme={null}
# S3
aws s3 cp test.txt s3://your-bucket/test.txt

# GCS
echo "test" | gsutil cp - gs://your-bucket/test.txt

# Local
touch /path/to/snapshots/test.txt
```

***

## Getting Help

If you've tried the solutions above and still have issues:

1. **Check the logs:**
   * Agent: `docker logs basecut-agent`

2. **File a GitHub issue:**
   * [github.com/basecuthq/basecut/issues](https://github.com/basecuthq/basecut/issues)
   * Include: error message, configuration file, command used, Basecut version

3. **Contact support:**
   * Email: [support@basecut.dev](mailto:support@basecut.dev)
   * Include: account email, snapshot name, timestamp of error

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Environment Variables" icon="terminal" href="/advanced/environment-variables">
    Complete configuration reference
  </Card>

  <Card title="Agent Deployment" icon="server" href="/advanced/agent-deployment">
    Self-hosted agent setup and debugging
  </Card>

  <Card title="CLI Reference" icon="terminal" href="/cli-reference/snapshot-create">
    Complete command documentation
  </Card>
</CardGroup>
