Question

Fix “Package Is Not in GOROOT” Errors in Go Projects

Question

A Go project that previously built successfully now fails with this error when I build a package:

start.go: package project/game is not in GOROOT (C:\Go\src\project\game)

My folders are arranged under C:\Users\username like this:

src/
└── project/
    ├── game/
    │   ├── entity/
    │   │   └── whatever.go
    │   └── game_stuff.go
    └── server/

My environment variables are:

GOROOT=C:\Go
GOPATH=C:\Users\ketchup\go

I ran go mod init separately for project/game/entity, project/game, and project/server. GoLand runs the following command when building:

C:\Go\bin\go.exe build -o C:\Users\ketchup\AppData\Local\Temp\___go_build_project_server.exe project/server

Why is Go searching in GOROOT, and how should I structure the project and modules so that project/server can import project/game correctly?

Short Answer

You will learn why an unresolved Go import can produce a “package is not in GOROOT” message, how Go modules determine import paths, and how to organize related packages under one module. You will also see when GOPATH matters and which go build command to run from a module-based project.

Concept

Go needs to map every import path, such as:

import "example.com/project/game"

to source code on disk. The way it performs that mapping depends on whether the project uses Go modules or the older GOPATH workspace workflow.

In a modern Go module project, a go.mod file defines the module's import-path prefix:

module example.com/project

With that module declaration, a directory named game beside go.mod is imported as:

import "example.com/project/game"

A directory named server is another package in the same module, not another module.

The error:

package project/game is not in GOROOT (C:\Go\src\project\game)

means Go could not resolve the import as a package in the current module, a required dependency module, or the configured workspace. It then reports the location where it checked in the Go installation. GOROOT is where Go itself is installed, often C:\Go; application code normally does not belong there.

A common cause is creating separate go.mod files for directories that are really packages of one application. Once game has its own module, it is no longer automatically part of the server module. Separate modules require explicit versioned dependencies, a local replace directive, or a Go workspace. For a single application, one module at the shared root is simpler and usually correct.

GOPATH is mainly relevant for older projects that do not use modules and for locations such as the Go binary cache. In module-based development, source code can live outside GOPATH.

Mental Model

Think of a module as a building with one street address.

  • The module line in go.mod is the building's address, for example example.com/project.
  • Each subdirectory is a room in that building: game, game/entity, and server.
  • An import path is the full address of a room: example.com/project/game.

If every room gets its own building registration (go.mod), they are no longer automatically connected. To visit another building, Go needs explicit directions: a dependency version, a replace rule, or a workspace.

GOROOT is the Go toolchain's own building. Go checking there does not mean your code should be moved there; it usually means Go did not find your requested address in the places it expected.

Take Quiz

Syntax and Examples

For one application containing game and server, use one module at the shared root.

project/
├── go.mod
├── game/
│   ├── game.go
│   └── entity/
│       └── player.go
└── server/
    └── main.go

Create the module from the project directory:

cd C:\Users\ketchup\project
go mod init example.com/ketchup/project
go mod tidy

go.mod should contain one module declaration:

module example.com/ketchup/project

go 1.22

Use the Go version installed on your computer. A repository hosted at github.com/name/project would normally use that URL as its module path.

Then server/main.go can import the sibling game package:

package main

import (
    "fmt"

    "example.com/ketchup/project/game"
)

func main() {
    fmt.Println(game.Message())
}

And game/game.go provides an exported function:

package game

func Message() string {
    return "Game package loaded"
}

Build or run from the module root:

go run ./server
go build ./server
go build ./...

The ./server form means “the directory named server relative to the current directory.” It avoids relying on a bare import path such as project/server.

Step by Step Execution

Consider this project:

project/
├── go.mod                     # module example.com/ketchup/project
├── game/
│   └── game.go                # package game
└── server/
    └── main.go                # package main

server/main.go contains:

package main

import (
    "fmt"
    "example.com/ketchup/project/game"
)

func main() {
    fmt.Println(game.Message())
}

When you run this from project:

go run ./server

Go performs these steps:

  1. It sees ./server and locates the server directory relative to the current directory.
  2. It walks upward from that directory until it finds project/go.mod.
  3. It reads the module path: example.com/ketchup/project.
  4. It sees the import example.com/ketchup/project/game.
  5. Because that import begins with the current module path, it maps the remaining /game to the local project/game directory.
  6. It compiles game, then compiles server, and finally runs the resulting executable.

If game/go.mod exists with a different module declaration, step 5 no longer treats game as an ordinary package within the root module. That is why accidental nested modules often cause confusing import errors.

Real World Use Cases

Go modules and correct import paths are used in nearly every Go project:

  • Web APIs: a cmd/api executable imports internal packages such as example.com/shop/api/handlers and example.com/shop/api/database.
  • Command-line tools: a cmd/tool command imports reusable logic from packages such as config, parser, and service.
  • Background workers: a worker package imports shared domain code from packages such as jobs, models, or queue.
  • Monorepos: several independently released services may use separate modules, coordinated with a go.work workspace during local development.
  • Libraries: a public module path tells downstream users exactly what to import and version, such as github.com/org/library/parser.
Take Quiz

Real Codebase Usage

Most Go repositories use one module for one deployable application or one versioned library.

A typical layout is:

example-app/
├── go.mod
├── cmd/
│   └── api/
│       └── main.go
├── internal/
│   ├── config/
│   └── service/
└── pkg/
    └── optionalpublicpackage/

Common project practices include:

  • One root go.mod: packages below it use imports beginning with the module path.
  • Relative package commands: developers run go test ./..., go vet ./..., and go build ./cmd/api from the module root.
  • internal packages: code under internal/ can be imported only by code in the allowed parent tree, helping keep implementation details private.
  • Dependency cleanup: go mod tidy adds missing dependency requirements and removes unused ones after imports change.
  • Explicit multi-module setup: when separate modules are intentional, each module has its own go.mod; local development commonly uses a go.work file or carefully scoped replace directives.

For the project in the question, remove the go.mod files inside game, entity, and server if they are all parts of one application. Keep one go.mod in the common project directory, then update imports to match its module declaration.

Common Mistakes

Creating a module for every package

This creates independent dependency boundaries unnecessarily:

project/go.mod
game/go.mod
server/go.mod

For a single application, use only:

project/go.mod
project/game/
project/server/

Importing a directory name instead of the module path

If go.mod says:

module example.com/ketchup/project

this import is wrong:

import "project/game"

Use the full module-based import instead:

import "example.com/ketchup/project/game"

Putting application code in GOROOT

Do not copy project packages into C:\Go\src. GOROOT belongs to the installed Go distribution. Keep it managed by the Go installer unless you are building Go itself.

Mixing a GOPATH-style folder with module assumptions

In old GOPATH mode, project/game would need to be located at:

%GOPATH%\src\project\game

But the listed source path and GOPATH do not match. More importantly, modern projects should generally use modules and not depend on this layout.

Building a bare import path from the wrong context

This command asks Go to resolve project/server as an import path:

go build project/server

From the module root, prefer:

go build ./server

Ignoring the active module in an IDE

GoLand uses the Go toolchain and the project/module configuration. Open the folder containing the intended root go.mod, then refresh Go modules or reopen the project after moving or deleting go.mod files.

Comparisons

ApproachHow packages are locatedRecommended use
Go modulesgo.mod module path plus directories and declared dependenciesDefault for modern Go projects
GOPATH workspace%GOPATH%/src/<import-path> directory layoutMaintaining legacy projects
One module, many packagesSubdirectories under one root go.modOne application or library with related packages
Multiple modulesEach module has its own go.mod and dependency graphIndependently versioned components
go work workspaceA go.work file connects local modulesLocal development across intentional multiple modules

A single module does not mean a single package. One module can contain many packages. A package is determined by a directory and its package declaration; a module is the larger unit that defines import-path ownership and dependencies.

Take Quiz

Cheat Sheet

GOROOT = Go installation directory
GOPATH = legacy workspace location and Go workspace-related paths
go.mod = module definition and dependency list

Create one module at the application root:

cd path\to\project
go mod init example.com/you/project
go mod tidy

Map directories to import paths:

go.mod module: example.com/you/project
project/game        -> example.com/you/project/game
project/game/entity -> example.com/you/project/game/entity

Useful commands from the module root:

go run ./server
go build ./server
go build ./...
go test ./...
go mod tidy
go env GOROOT GOPATH GOMOD

Rules to remember:

  • Do not put ordinary application code in GOROOT.
  • Do not create go.mod in every package of one application.
  • Imports must start with the module path declared in go.mod.
  • Use ./directory to target a local package directory.
  • If a directory intentionally has its own go.mod, it is a separate module.

FAQ

Why does Go say a package is not in GOROOT?

Go could not resolve the import through the current module, required modules, or workspace. The message shows that it also checked the Go installation source tree. Your application package usually does not belong in GOROOT.

Should I set GOPATH for a Go modules project?

Usually not for locating your project source. Module-based projects can live anywhere. GOPATH may still be used by Go for workspace-related directories and installed binaries.

Should every Go folder have a go.mod file?

No. Create a go.mod for each independently versioned module, not for every package directory. Most small applications need one root go.mod.

How do I know which module Go is using?

From the relevant directory, run:

go env GOMOD

It prints the path to the active go.mod, or an empty value when no module is active.

Why does go build ./server work differently from go build project/server?

./server is a filesystem-relative package pattern. project/server is treated as an import path that Go must resolve through module or GOPATH rules.

Can I use module project in go.mod?

It can work locally, but a globally unique module path such as github.com/yourname/project or example.com/yourname/project is better, especially if the code may be shared or published.

When should I use go.work?

Use go.work when you intentionally develop multiple separate modules together. It is not necessary when the directories are simply packages of one application.

Does GoLand cause this error?

Usually the underlying issue is Go module discovery, imports, or the build command. GoLand may expose it by opening the wrong directory or using a stale module configuration, but the Go command-line tools should be fixed first.

Take Quiz

Mini Project

Description

Create a small command-line application with a server command that imports a sibling game package from the same Go module. This demonstrates the relationship between a module path, directory structure, imports, and relative build commands.

Goal

Build and run a command that prints a message returned by a local package.

Requirements

Requirement 1

Take Quiz

Keep learning

Related questions

View more