Introduction Link to heading
If you have ever initialized a new Go project with go mod init main and later tried to write tests for it, you may have seen this cryptic error:
cannot import "main"
At first glance, this doesn’t make much sense — after all, your code and tests are both in package main. However, there’s a subtle interaction between how Go handles modules, packages, and test harnesses that causes this issue. Let’s walk through what’s actually happening.
Setting Up the Problem Link to heading
The go.mod File
Link to heading
When you initialize a new Go module for an executable project, it’s common to do something like:
go mod init main
That creates the following go.mod file:
module main
go 1.25.3
Then you might have a simple file like this:
package main
func main() {
square(4)
}
func square(n int) int {
return n * n
}
Now you decide to write a quick unit test in main_test.go:
package main
import "testing"
func TestSquare(t *testing.T) {
t.Log("Test successful")
}
At this point, everything looks fine — until you run:
go test
and get the following output:
# main.test
$WORK/b001/_testmain.go:14:8: could not import main (cannot import "main")
FAIL main [build failed]
FAIL
Why This Happens Link to heading
When you run go test, the Go toolchain generates a temporary test harness (a _testmain.go file). This harness imports the package under test so that it can invoke your test functions. Here’s the catch: the test harness must import the module under its module path. When your module path is literally "main", the compiler refuses — because main is reserved for executables and cannot be imported like a normal package. This only affects go test (and go test .), because those commands rely on the generated import. When you explicitly specify files (e.g., go test *.go), Go skips module resolution and compiles everything together manually, avoiding the import step entirely.
The Fix Link to heading
Option 1: Rename the Module Link to heading
Change your go.mod file to use a different name, for example:
module myapp
go 1.25.3
Then rerun:
go test
You should now see:
ok myapp 0.35s
Option 2: Move Testable Code Out of main
Link to heading
In most cases, your main package should be minimal — it should only wire dependencies together. Any functions that need unit tests should live in a separate package (for example, internal/mathutil), which can then be imported both from your main application and from your test files.
Key Takeaways Link to heading
- The Go test harness always imports the package under test.
- A module named
maincan’t be imported, which breaks that process. - Rename your module or move testable code to another package.
- Reserve
mainstrictly for integration and startup logic.
Conclusion Link to heading
This issue isn’t a compiler bug — it’s just an edge case that surfaces when your module path collides with Go’s internal naming conventions. If you ever see cannot import "main" when testing, remember: rename the module or refactor your code to follow Go’s standard package layout.