diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
index 63fd13f7544db3..50fe23f7214ca2 100644
--- a/src/cmd/go/internal/work/exec.go
+++ b/src/cmd/go/internal/work/exec.go
@@ -1899,12 +1899,21 @@ func (b *Builder) installHeader(ctx context.Context, a *Action) error {
 // regular outputs (instrumented source files) the cover tool also
 // writes a separate file (appearing first in the list of outputs)
 // that will contain coverage counters and meta-data.
+//
+// When an overlay is in use, it ensures the coverage tool processes the overlaid
+// files rather than the original source files.
 func (b *Builder) cover(a *Action, infiles, outfiles []string, varName string, mode string) ([]string, error) {
 	pkgcfg := a.Objdir + "pkgcfg.txt"
 	covoutputs := a.Objdir + "coveroutfiles.txt"
 	odir := filepath.Dir(outfiles[0])
 	cv := filepath.Join(odir, "covervars.go")
 	outfiles = append([]string{cv}, outfiles...)
+	overlayInfiles := make([]string, 0, len(infiles))
+	for _, f := range infiles {
+		overlayPath := fsys.Actual(f)
+		overlayInfiles = append(overlayInfiles, overlayPath)
+	}
+
 	if err := b.writeCoverPkgInputs(a, pkgcfg, covoutputs, outfiles); err != nil {
 		return nil, err
 	}
@@ -1914,7 +1923,7 @@ func (b *Builder) cover(a *Action, infiles, outfiles []string, varName string, m
 		"-var", varName,
 		"-outfilelist", covoutputs,
 	}
-	args = append(args, infiles...)
+	args = append(args, overlayInfiles...)
 	if err := b.Shell(a).run(a.Objdir, "", nil,
 		cfg.BuildToolexec, args); err != nil {
 		return nil, err
diff --git a/src/cmd/go/testdata/script/cover_overlay.txt b/src/cmd/go/testdata/script/cover_overlay.txt
new file mode 100644
index 00000000000000..0440acf2aa50d1
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_overlay.txt
@@ -0,0 +1,77 @@
+# Test that coverage works correctly with overlays
+
+env GO111MODULE=on
+
+mkdir covmod
+cd covmod
+
+-- go.mod --
+module example.com/covmod
+
+go 1.25
+
+-- a.go --
+package a
+
+func Hello() string { 
+    return "Hello: World"
+}
+
+func Helper() string {
+    return "helper"
+}
+
+-- a_test.go --
+package a
+
+import "testing"
+
+func TestHello(t *testing.T) {
+	got := Hello()
+	expected := "Hello: World"
+	if got != expected {
+		t.Fatalf("Hello() = %q, want %q", got, expected)
+	}
+}
+
+func TestHelper(t *testing.T) {
+	got := Helper()
+	expected := "helper"
+	if got != expected {
+		t.Fatalf("Helper() = %q, want %q", got, expected)
+	}
+}
+
+-- overlay/a.go --
+package a
+
+func Hello() string {
+    panic("overlay")
+}
+
+func Helper() string {
+    panic("overlay helper")
+}
+
+-- overlay.json --
+{"Replace": {"a.go": "overlay/a.go"}}
+
+exists overlay.json
+
+go mod tidy
+
+go test -v
+
+! exec sh -c '! go test -overlay=overlay.json -coverpkg=example.com/covmod 2>&1 | grep -q "panic: overlay"'
+
+! exec sh -c '! go test -overlay=overlay.json -run=TestHello -coverpkg=example.com/covmod 2>&1 | grep -q "panic: overlay"'
+
+! exec sh -c '! go test -overlay=overlay.json -run=TestHelper -coverpkg=example.com/covmod 2>&1 | grep -q "panic: overlay helper"'
+
+! go test -overlay=overlay.json -coverpkg=example.com/covmod -coverprofile=coverage.txt
+
+exists coverage.txt
+
+! grep -q 'overlay/a\.go' coverage.txt
+
+rm -f coverage.txt
\ No newline at end of file