## TL;DR
ECONNREFUSED means nothing is listening where Cypress knocked. Start your app before the Cypress run and block until a health endpoint answers. Nine times out of ten the app simply was not up yet, or the port in the URL is wrong.

## Error
```text
CypressError: cy.request() failed trying to load:

YOUR_HOST/api/health

We attempted to make an http request to this URL but the request failed without a response.

The request we sent was:

Method: GET
URL: YOUR_HOST/api/health

The error was:

Error: connect ECONNREFUSED YOUR_HOST:3000
```

## Steps
1. From the same machine or container that runs Cypress, curl the health endpoint by hand. Expected: a 200 response, which proves the app is reachable.
2. If step 1 fails, start the app and wait for it before launching Cypress:
```text
npx start-server-and-wait start YOUR_HOST/api/health "npx cypress run"
```
Expected: the wait command exits only after the health endpoint answers.
3. Check that baseUrl in cypress.config.js uses the same host and port the app actually listens on. Expected: the config URL and the app listen port match exactly.
4. In Docker Compose or multi-container CI, use the service name as the host and add a healthcheck dependency so Cypress starts after the app is ready. Expected: Cypress never starts against a cold container.
5. Re-run the suite. Expected: cy.request() gets responses instead of refusals.

## When to use
- cy.request() or cy.visit() fails with ECONNREFUSED
- The suite runs in CI or Docker but works on your machine
- You recently changed the app port, the start command, or the CI job order

## When not to use
- The server responds with 4xx or 5xx (the app is up; the request or the app logic is wrong)
- DNS lookup fails (a networking or hostname problem, not a startup-order problem)
- The app crashes during boot (fix the crash first, then come back)

## Tool compatibility
- Cypress 12 through 14, cy.request() and cy.visit()
- start-server-and-wait 3.x or the wait-on 7.x package
- Docker Compose, GitHub Actions, CircleCI, Jenkins

## Variant phrasings
### cy.request failed without a response in docker
Same fix. The Cypress container usually starts before the app container is listening. Wait on the service hostname, not a fixed sleep.
### connect ECONNREFUSED in CI only
Compare the CI start command with your local one. CI often skips the dev server step or binds a different port.

## Why it happens
Cypress does not start your app for you. Locally the dev server is already running from your terminal, so requests succeed. In CI or a fresh container nothing is listening yet, or the job launches Cypress in parallel with the server, so the TCP connection is refused.

## Edge cases
- Health endpoint answers but API calls still refuse: the app listens on one port and the API on another. Point each URL at the right port.
- Works with npm start but not in CI: the CI step may run the server in the background without waiting. Keep the wait step in the same job.
- Intermittent refusals under load: the server is overwhelmed or restarting. Add retries around the health check and check server logs.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_MGiPh8a0EZgDtmlwpiF9xQ
