# Fly.io deploy issues

Common Fly.io deploy problems and their fixes. Reference for every project.

---

## Issue #1: Binary exits immediately with code 0

### Symptoms

- Deploy completes without errors
- Machine starts but exits immediately
- Logs show: `Main child exited normally with code: 0`
- No application logs (not even the first print/log)

### Possible causes

#### 1. Dependency version mismatch (most common)

**Real example:** the `rand` crate has incompatible APIs between versions:

| rand 0.8              | rand 0.9                 |
| --------------------- | ------------------------ |
| `rand::thread_rng()`  | `rand::rng()`            |
| `rng.gen_range(a..b)` | `rng.random_range(a..b)` |
| `rng.gen_bool(p)`     | `rng.random_bool(p)`     |
| `rng.gen::<T>()`      | `rng.random::<T>()`      |

The code compiles but the binary fails silently at runtime.

**Fix:**

1. Compare dependency versions against services that work
2. Use the same version as existing services
3. Update the code syntax if needed
4. Run `cargo update`

#### 2. Wrong architecture (ARM vs x86)

If you develop on a Mac M1/M2 (ARM64), the binary may compile for ARM instead of x86_64.

**Check:**

```bash
docker run --rm --entrypoint sh <image> -c "ldd /app/binary"
# Should show: linux-vdso.so.1, libc.so.6, etc. for x86_64
```

**Fix:**
Fly.io uses remote builders that target amd64, but if you build locally:

```dockerfile
FROM --platform=linux/amd64 rust:1.84 AS build
```

#### 3. Missing environment variables

If a critical variable is missing, the binary may exit with no visible error.

**Check:**

```bash
flyctl secrets list -a <app>
flyctl ssh console -a <app> -C "printenv"
```

### Recommended debug process

1. **Check the full logs:**

   ```bash
   flyctl logs -a <app> --no-tail | head -50
   ```

2. **Create a temporary app to test:**

   ```bash
   flyctl apps create <app>-test
   flyctl secrets set ... -a <app>-test
   flyctl deploy -c fly-test.toml --ha=false
   ```

3. **Compare against services that work:**
   - Rust versions in the Dockerfile
   - Dependency versions in Cargo.toml
   - fly.toml configuration

4. **If the test works, deploy to production:**
   ```bash
   flyctl deploy --ha=false -a <app-original>
   flyctl apps destroy <app>-test --yes
   ```

---

## Issue #2: Rate limiting on restart loops

### Symptoms

- App keeps trying to restart
- Error: `could not find a good candidate within X attempts`
- Machine ends up in `stopped` state

### Cause

Fly.io rate-limits restarts to avoid infinite loops.

### Fix

1. Wait a few minutes
2. Start manually: `flyctl machine start <machine-id> -a <app>`
3. Or redeploy: `flyctl deploy --ha=false`

---

## Pre-deploy checklist

- [ ] Verify the local build works: `cargo build --release`
- [ ] Compare Cargo.toml with services that work
- [ ] Verify configured secrets: `flyctl secrets list`
- [ ] Review fly.toml (region, env vars, ports)
- [ ] When in doubt, test on a temporary app first

---
