Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

  • 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 baseUrl cannot 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

4. 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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 Container Linux Devops Programming Coding T-Shirt
  • 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 nyc invocation 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.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.