# LiteLLM DB Migration Pitfall — Encrypted Models Don't Survive pg_dump

**Date:** Jul 13, 2026
**Root cause:** LiteLLM encrypts model parameters (api_key, model name, provider) in `LiteLLM_ProxyModelTable` using the `LITELLM_SALT_KEY`. A `pg_dump` + `pg_restore` to a new server will list the models in `/v1/models` but completions fail with "Invalid model name passed."

**Symptom:** Same Docker image (v1.84.0), same SALT_KEY, same DB dump. Models appear in the listing but every completion returns `400: Invalid model name passed in model=X. Call /v1/models to view available models for your key.`

**Why:** The encryption uses not just SALT_KEY but also some per-installation factor (possibly container hostname, Docker network IP, or a runtime-generated nonce) that differs between hosts. Identical SALT_KEY, identical DB, identical image — still can't decrypt.

**Fix:** Do NOT rely on DB migration for models. Instead:
1. Export the list of model names from the old box
2. Recreate each model fresh on the new box via the `/model/new` endpoint
3. Test each model with a completion

```bash
# List models on old box
curl -s https://admin-ai.itpropartner.com/v1/models -H "Authorization: Bearer $KEY" | jq -r '.data[].id' > models.txt

# Recreate on new box
while read model; do
  curl -s http://127.0.0.1:4000/model/new -X POST \
    -H "Authorization: Bearer $MASTER_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"model_name\":\"$model\",\"litellm_params\":{\"model\":\"$model\",\"custom_llm_provider\":\"openai\",\"api_base\":\"https://admin-ai.itpropartner.com/v1\",\"api_key\":\"$ADMIN_AI_KEY\"}}"
done < models.txt
```

**Alternative:** If migrating TO a self-hosted LiteLLM that replaces the old admin-ai proxy, configure models to use OpenRouter directly instead of routing through admin-ai. This avoids the proxy-in-a-loop problem post-DNS-cutover.

**Credentials table survives** — The `LiteLLM_CredentialsTable` decrypts fine after migration. Only `LiteLLM_ProxyModelTable` entries fail.

**Post-migration config.yaml requirement:** The new LiteLLM needs a `config.yaml` with `database_url`, `store_model_in_db: true`, and `enforce_database: true`. Without it, models created via API are lost on restart.
