Go version

go version go1.24.4 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/tech/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/tech/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build29968082=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/tech/tool_vendor/go.mod'
GOMODCACHE='/home/tech/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/tech/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/tech/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.4.linux-amd64'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/tech/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/tech/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.4.linux-amd64/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.24.4'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Create a minimal project: go.mod

module split_tool

go 1.24.4

require github.com/google/uuid v1.6.0

main.go

package main

import (
    "fmt"

    "github.com/google/uuid"
)

func main() {
    id := uuid.New()
    fmt.Println(id)
}

Vendor dependencies: go mod tidy && go mod vendor

Add golangci-lint as a tool into a different .mod file to separate project and tool dependencies:

go mod init -modfile=golangci-lint.mod split_tool/golangci-lint
go get -tool -modfile=golangci-lint.mod github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6

golangci-lint.mod at this point contains:

module split_tool/golangci-lint

go 1.24.4

tool github.com/golangci/golangci-lint/v2/cmd/golangci-lint

require (
    ...
)

Now try running golangci-lint:

$ go tool -modfile=golangci-lint.mod golangci-lint run
go: inconsistent vendoring in /home/tech/tool_vendor:
        4d63.com/gocheckcompilerdirectives@v1.3.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        ...
        github.com/google/uuid@v1.6.0: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod

        To ignore the vendor directory, use -mod=readonly or -mod=mod.
        To sync the vendor directory, run:
                go mod vendor

This is not unexpected, since we have a vendor directory. Now let's try to set -mod=mod as suggested, since we don't actually need to vendor tool dependencies.

What did you see happen?

-mod=mod cannot be passed to go tool:

➜  ~/tool_vendor go tool -modfile=golangci-lint.mod -mod=mod golangci-lint version
flag provided but not defined: -mod
usage: go tool [-n] command [args...]
Run 'go help tool' for details.
➜  ~/tool_vendor go tool -mod=mod -modfile=golangci-lint.mod golangci-lint version
flag provided but not defined: -mod
usage: go tool [-n] command [args...]
Run 'go help tool' for details.
➜  ~/tool_vendor go -mod=mod tool -modfile=golangci-lint.mod golangci-lint version
flag provided but not defined: -mod
Go is a tool for managing Go source code.

Usage:
...
Use "go help <topic>" for more information about that topic.

➜  ~/tool_vendor GOFLAGS=-mod=mod go tool -modfile=golangci-lint.mod golangci-lint version
go: inconsistent vendoring in /home/tech/tool_vendor:
        4d63.com/gocheckcompilerdirectives@v1.3.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        ...
        github.com/google/uuid@v1.6.0: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod

        To ignore the vendor directory, use -mod=readonly or -mod=mod.
        To sync the vendor directory, run:
                go mod vendor

What did you expect to see?

go tool to ignore vendor directory when flag -mod=mod is passed and run golangci-lint: go tool -modfile=golangci-lint.mod -mod=mod golangci-lint version

Comment From: gabyhelp

Related Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

Comment From: dmitshur

CC @golang/command-line.

Comment From: seankhliao

See #73968 The design of go tool expects a single unified module graph. -mod=mod is not the right fix as it allows modifying the .mod and .sum files.

Comment From: TechnoStrife

How about -mod=readonly then? I wouldn't have opened an issue if this wasn't suggested by go tool itself @seankhliao