# Dify + Qdrant "Connection Refused" Error

**Problem:** Dify worker shows `qdrant_client.http.exceptions.ResponseHandlingException: [Errno 111] Connection refused`

**Symptoms:**
- Documents stuck in "Queuing" status
- Re-indexing fails
- Qdrant container is running and healthy
- `curl http://qdrant:6333/collections` works from worker container
- But Python Qdrant client cannot connect

**Root Cause:**
Dify's Qdrant client expects `QDRANT_URL` environment variable in full URL format (`http://host:port`), NOT separate `QDRANT_HOST` and `QDRANT_PORT` variables.

**Diagnosis:**
```bash
# Check what Dify sees
docker exec firefrost-codex_dify-worker_1 python3 -c "
from configs import dify_config
print('QDRANT_URL:', dify_config.QDRANT_URL)
"

# If output is "None", the variable is not set correctly
```

**Solution:**

1. **Check docker-compose.yml environment section:**
```yaml
dify-api:
  environment: &dify-env
    VECTOR_STORE: qdrant
    QDRANT_URL: http://qdrant:6333  # ✅ CORRECT - full URL
    # NOT THIS:
    # QDRANT_HOST: qdrant            # ❌ WRONG
    # QDRANT_PORT: 6333              # ❌ WRONG
```

2. **Fix docker-compose.yml:**
```bash
cd /opt/firefrost-codex

# Remove old format if present
sed -i '/QDRANT_HOST:/d' docker-compose.yml
sed -i '/QDRANT_PORT:/d' docker-compose.yml

# Add correct format (if not already present)
# Manually edit to add under VECTOR_STORE line:
# QDRANT_URL: http://qdrant:6333
```

3. **Recreate containers (required for env var changes):**
```bash
docker-compose down
docker-compose up -d
```

4. **Verify:**
```bash
# Should show: QDRANT_URL=http://qdrant:6333
docker exec firefrost-codex_dify-worker_1 env | grep QDRANT_URL
```

5. **Test indexing:**
- Go to Dify web interface
- Navigate to Knowledge Base
- Click "Re-index"
- Documents should start turning green (Indexed status)

**Why This Happens:**

Dify's `QdrantConfig` class (in `/app/api/configs/middleware/vdb/qdrant_config.py`) defines:

```python
QDRANT_URL: str | None = Field(
    description="URL of the Qdrant server (e.g., 'http://localhost:6333')",
    default=None,
)
```

The older `QDRANT_HOST` / `QDRANT_PORT` format is NOT recognized by modern Dify versions.

**Common Mistakes:**

1. **Hardcoded IP instead of service name:**
```yaml
QDRANT_URL: http://172.19.0.4:6333  # ❌ IP can change on restart
QDRANT_URL: http://qdrant:6333      # ✅ Service name is stable
```

2. **Using .env file but docker-compose.yml overrides:**
- docker-compose.yml environment values OVERRIDE .env file
- Always check docker-compose.yml first

3. **Forgetting to recreate containers:**
```bash
docker-compose restart  # ❌ Does NOT reload environment variables
docker-compose down && docker-compose up -d  # ✅ Recreates with new env
```

**Verification Checklist:**

- [ ] Qdrant container is running: `docker ps | grep qdrant`
- [ ] Network connectivity works: `docker exec firefrost-codex_dify-worker_1 curl -s http://qdrant:6333/collections`
- [ ] Environment variable is set: `docker exec firefrost-codex_dify-worker_1 env | grep QDRANT_URL`
- [ ] Variable format is correct: Should be `http://qdrant:6333`, not empty or IP
- [ ] Containers were recreated after config change
- [ ] No errors in worker logs: `docker-compose logs dify-worker | grep -i error`

**Related Issues:**

- See: `docs/tasks/firefrost-codex/` for Phase 5 deployment details
- See: Chronicler #25 (The Foundation) memorial for initial deployment
- See: Chronicler #26 session for troubleshooting this exact issue

**Created:** February 24, 2026  
**Created By:** Chronicler #26  
**Issue Resolved:** February 24, 2026 (3+ hour debugging session)

---

💙🔥❄️

**The best debugging sessions are the ones that become documentation for the next person.**
