Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
If Cypress can’t fetch coverage in Docker, first make sure the application is instrumented and exposes coverage data, then set the coverage URL to an address reachable from the Cypress process—not an assumed localhost. For backend coverage, the endpoint must return JSON and match env.codeCoverage.url. The plugin’s debug trace can then show whether the failure is at reset, fetch, write, merge, or report generation.
How Cypress code coverage collection works
@cypress/code-coverage gathers coverage data produced by an instrumented application. For frontend coverage, the running app must expose Istanbul coverage data, normally through a global coverage object. For backend coverage, the server must expose that data through a JSON endpoint. Cypress and the plugin then collect and combine the data and generate a report.
This means a fetch error is not necessarily a report-generation problem. The application may not have produced coverage data at all, or Cypress may be unable to reach the backend endpoint from inside its container. Find which stage fails before changing Docker ports or plugin settings.
Recommended Free Tools
1. Confirm that the application is instrumented
Start here even if the app loads and tests pass. A passing test does not prove that the code Cypress is testing was built or run with coverage instrumentation. Without coverage data, the plugin has nothing to fetch or merge.
#1 Best Overall
- Check that the frontend build or backend process used for the test is instrumented to expose Istanbul coverage data.
- Confirm that the running application actually has the coverage object when a test reaches the relevant code.
- If the app is not instrumented, fix the build or server instrumentation first. Changing
baseUrlcannot make missing coverage data appear.
Instrumentation is application- and build-specific; the plugin does not instrument an arbitrary running app merely because its support file and task are registered.
2. Register both parts of the Cypress plugin
The plugin setup has two required pieces: its support-file import and its Node event task. Use the support file configured for the test type you run, and register the task inside setupNodeEvents. The following CommonJS example shows the wiring; keep any other configuration your project already needs.
Support file
require('@cypress/code-coverage/support');
Cypress configuration
const { defineConfig } = require('cypress');
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
require('@cypress/code-coverage/task')(on, config);
return config;
},
},
});
Install @cypress/code-coverage as a development dependency before using these snippets. Registering only one half is incomplete: the support import and Node task do different jobs, and both are required. Return the configuration object from setupNodeEvents so Cypress receives the resulting configuration.
When configured and supplied with coverage data, the plugin saves combined data under .nyc_output and generates reports viewable under coverage/index.html. If neither output appears, use the debug trace to determine whether collection failed before the report stage.
3. Expose backend coverage as JSON
If the code you need to measure runs on a backend, Cypress needs an HTTP endpoint that returns its coverage object as JSON. A conventional route is GET /__coverage__. Express applications can expose the data with the plugin’s Express middleware; with another server, implement a route that returns the global coverage object itself.
Set env.codeCoverage.url to the endpoint’s full URL. The hostname and port must be reachable from the Cypress process, not merely from a browser or command running on the Docker host. For example, if Cypress can reach the app at http://app:3000 on its network, the endpoint would use that reachable origin plus /__coverage__. Treat that as an example, not a universal Compose hostname or port.
Rank #3
Verify all three pieces together: the backend process is instrumented, its route returns JSON coverage data, and env.codeCoverage.url points to that exact route using an address Cypress can reach. A route that exists but returns HTML, an error page, or no coverage object does not satisfy this requirement.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstall4. Use Docker addresses from Cypress’s point of view
localhost is relative to the process making the request. When Cypress runs in a container, localhost usually means that Cypress container—not the application container and not automatically the host machine. A URL that works in a host shell can therefore fail when the plugin fetches coverage inside Docker.
Set e2e.baseUrl to the application origin reachable from the Cypress process. Use a matching reachable address for env.codeCoverage.url when the backend coverage endpoint is on that application. In Docker Compose, container-to-container traffic commonly uses the service name and the port on which the service listens; a host-mapped port is commonly for traffic entering from outside the Compose network. These are operational Docker conventions, not a guarantee about your project’s network.
Check the actual Compose network, service names, listening port, and bind address. The application must listen on an interface that allows the Cypress container to connect; a service bound only to its own loopback interface may not be reachable by another container. Do not copy a host URL into container configuration without checking which process resolves it.
Cypress uses baseUrl to prefix relative cy.visit() and cy.request() calls, and checks the configured URL before running. Relative cy.request() calls resolve against the visited host or baseUrl; if Cypress cannot determine a host, it throws. These behaviors help diagnose application requests, but the backend coverage fetch still needs its own correct full URL in env.codeCoverage.url.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
5. Trace the failing stage with debug logging
Run Cypress with DEBUG=code-coverage in the environment of the Cypress process. Read the messages in order and identify the last successful operation. The trace can show reset activity, coverage-file writes, report saving, and the command used to invoke nyc.
Best Value
- Docker, Docker Swarm, Docker Compose, Programmer, Developer, Coding, Programming, Software Engineer, Code, DevOps, Deploy, Deployment, Kubernetes, Salt, Puppet, Chef, Terraform, Container, AWS, Azure, Cloud, Geek, Funny, Computer, Software, Tech, IT
- Integration, Scrum, Compile, Compilation, Science, Bug, Debug, Python, Linux, Java, Javascript, Scala, Dotnet, Kotlin
- Lightweight, Classic fit, Double-needle sleeve and bottom hem
- Failure before a fetch: check plugin registration, reset behavior, and whether instrumentation is active.
- Fetch or timeout: check the endpoint URL from inside the Cypress container, confirm it returns JSON, and inspect the size of the coverage payload.
- Write or merge failure: check the trace for coverage-file writes and whether the expected coverage data was received.
- Report failure: inspect the logged
nycinvocation and report-save messages; collection may have succeeded even if report generation did not.
When sending a large coverage object causes a timeout, configure sendCoverageBatchSize in the plugin’s expose configuration so the data is sent in batches. This addresses payload-size pressure; it does not fix an unreachable endpoint or missing instrumentation.
6. Match the fix to the symptom
| Symptom or change | What to check first | Likely next action |
|---|---|---|
| The app works locally, but coverage fetch fails in Docker | Whether localhost or a host-mapped address is being used from the Cypress container |
Use the hostname and port reachable from Cypress; verify the Docker network and listening interface |
| No coverage files or report appear | Instrumentation, support-file import, and registered Node task | Ensure the running app exposes coverage data and both plugin setup pieces are active |
| Frontend coverage works but backend coverage is absent | Whether a JSON coverage endpoint exists and env.codeCoverage.url matches it |
Expose the backend coverage object and set its full reachable URL |
| Fetch begins but times out with a large object | Debug trace and coverage payload size | Set sendCoverageBatchSize in the plugin’s expose configuration |
| The failure started after an upgrade | The last working and first failing Cypress and plugin versions | Compare the released plugin versions and identify which change coincides with the new behavior |
Or skip the browser setup
ScreenshotNeo is a separate option for taking website screenshots; it does not collect Cypress code coverage or repair a Docker coverage fetch. If you also need a clean screenshot of a page without setting up a browser capture service, one GET request returns an image or PDF. See the ScreenshotNeo API documentation for request options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The same request in Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Or in Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. It also offers an MCP server for AI agents, including Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Sign up for ScreenshotNeo’s free plan to try it with 1,000 screenshots a month and no card.
Cost and reliability considerations for coverage
For code coverage, the useful reliability signal is the stage-level trace, not simply whether the test command exited successfully. Keep application and Cypress URLs explicit for the network path each process uses, and preserve the debug output when a failure is intermittent. If the payload is large, batching may help; if the endpoint is unreachable or the app is not instrumented, batching is not a substitute for fixing that cause.
If the behavior changed after an upgrade, compare the plugin releases used by the last passing and first failing runs rather than changing several variables at once. No general timeout threshold or universally correct Docker hostname applies across projects; those depend on the actual network, service configuration, and payload.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →

