Go Modules Reference
Introduction
Modules are how Go manages dependencies.
This document is a detailed reference manual for Go’s module system. For anintroduction to creating Go projects, seeHow to Write GoCode. For information on using modules,migrating projects to modules, and other topics, see the blog series startingwithUsing Go Modules.
Modules, packages, and versions
Amodule is a collection of packages that are released, versioned,and distributed together. Modules may be downloaded directly from versioncontrol repositories or from module proxy servers.
A module is identified by amodule path, which is declaredin ago.mod file, together with information about themodule’s dependencies. Themodule root directory is the directorythat contains thego.mod file. Themain module is the modulecontaining the directory where thego command is invoked.
Eachpackage within a module is a collection of source files in thesame directory that are compiled together. Apackage path is themodule path joined with the subdirectory containing the package (relative to themodule root). For example, the module"golang.org/x/net" contains a package inthe directory"html". That package’s path is"golang.org/x/net/html".
Module paths
Amodule path is the canonical name for a module, declared with themodule directive in the module’sgo.modfile. A module’s path is the prefix for package paths withinthe module.
A module path should describe both what the module does and where to find it.Typically, a module path consists of a repository root path, a directory withinthe repository (usually empty), and a major version suffix (only for majorversion 2 or higher).
- Therepository root path is the portion of the module path thatcorresponds to the root directory of the version control repository where themodule is developed. Most modules are defined in their repository’s rootdirectory, so this is usually the entire path. For example,
golang.org/x/netis the repository root path for the module of the samename. SeeFinding a repository for a module path for informationon how thegocommand locates a repository using HTTP requests derivedfrom a module path. - If the module is not defined in the repository’s root directory, themodule subdirectory is the part of the module path that names thedirectory, not including the major version suffix. This also serves as aprefix for semantic version tags. For example, the module
golang.org/x/tools/goplsis in thegoplssubdirectory of the repositorywith root pathgolang.org/x/tools, so it has the module subdirectorygopls. SeeMapping versions to commits andModuledirectories within a repository. - If the module is released at major version 2 or higher, the module path mustend with amajor version suffix like
/v2. This may or may not be part of the subdirectory name. For example, themodule with pathgolang.org/x/repo/sub/v2could be in the/subor/sub/v2subdirectory of the repositorygolang.org/x/repo.
If a module might be depended on by other modules, these rules must be followedso that thego command can find and download the module. There are alsoseverallexical restrictions on characters allowed inmodule paths.
A module that will never be fetched as a dependency of any other module may useany valid package path for its module path, but must take care not to collidewith paths that may be used by the module’s dependencies or the Go standardlibrary. The Go standard library uses package paths that do not contain a dot inthe first path element, and thego command does not attempt to resolve suchpaths from network servers. The pathsexample andtest are reserved forusers: they will not be used in the standard library and are suitable for use inself-contained modules, such as those defined in tutorials or example code orcreated and manipulated as part of a test.
Versions
Aversion identifies an immutable snapshot of a module, which may beeither arelease or apre-release. Each version starts with the letterv, followed by a semantic version. SeeSemantic Versioning2.0.0 for details on how versions areformatted, interpreted, and compared.
To summarize, a semantic version consists of three non-negative integers (themajor, minor, and patch versions, from left to right) separated by dots. Thepatch version may be followed by an optional pre-release string starting with ahyphen. The pre-release string or patch version may be followed by a buildmetadata string starting with a plus. For example,v0.0.0,v1.12.134,v8.0.5-pre, andv2.0.9+meta are valid versions.
Each part of a version indicates whether the version is stable and whether it iscompatible with previous versions.
- Themajor version must be incremented and the minorand patch versions must be set to zero after a backwards incompatible changeis made to the module’s public interface or documented functionality, forexample, after a package is removed.
- Theminor version must be incremented and the patchversion set to zero after a backwards compatible change, for example, after anew function is added.
- Thepatch version must be incremented after a changethat does not affect the module’s public interface, such as a bug fix oroptimization.
- The pre-release suffix indicates a version is apre-release. Pre-release versions sort beforethe corresponding release versions. For example,
v1.2.3-precomes beforev1.2.3. - The build metadata suffix is ignored for the purpose of comparing versions.The go command accepts versions with build metadata and converts them topseudo-versions to maintain the total ordering between versions.
- The special suffix
+incompatibledenotes a version released beforemigrating to modules version major version 2 or later (seeCompatibilitywith non-module repositories). - The special suffix
+dirtyis appended to the version information of abinary when it’s built with a Go toolchain 1.24 or later within a validlocal Version Control System (VCS) repository that contains uncommittedchanges in the working directory.
- The special suffix
A version is considered unstable if its major version is 0 or it has apre-release suffix. Unstable versions are not subject to compatibilityrequirements. For example,v0.2.0 may not be compatible withv0.1.0, andv1.5.0-beta may not be compatible withv1.5.0.
Go may access modules in version control systems using tags, branches, orrevisions that don’t follow these conventions. However, within the main module,thego command will automatically convert revision names that don’t followthis standard into canonical versions. Thego command will also remove buildmetadata suffixes (except for+incompatible) as part of this process. This mayresult in apseudo-version, a pre-release version thatencodes a revision identifier (such as a Git commit hash) and a timestamp from aversion control system. For example, the commandgo get golang.org/x/net@daa7c041 will convert the commit hashdaa7c041 into thepseudo-versionv0.0.0-20191109021931-daa7c04131f5. Canonical versions arerequired outside the main module, and thego command will report an error if anon-canonical version likemaster appears in ago.mod file.
Pseudo-versions
Apseudo-version is a specially formattedpre-releaseversion that encodesinformation about a specific revision in a version control repository. Forexample,v0.0.0-20191109021931-daa7c04131f5 is a pseudo-version.
Pseudo-versions may refer to revisions for which nosemantic versiontags are available. They may be used to testcommits before creating version tags, for example, on a development branch.
Each pseudo-version has three parts:
- A base version prefix (
vX.0.0orvX.Y.Z-0), which is either derived from asemantic version tag that precedes the revision orvX.0.0if there is nosuch tag. - A timestamp (
yyyymmddhhmmss), which is the UTC time the revision wascreated. In Git, this is the commit time, not the author time. - A revision identifier (
abcdefabcdef), which is a 12-character prefix of thecommit hash, or in Subversion, a zero-padded revision number.
Each pseudo-version may be in one of three forms, depending on the base version.These forms ensure that a pseudo-version compares higher than its base version,but lower than the next tagged version.
vX.0.0-yyyymmddhhmmss-abcdefabcdefis used when there is no known baseversion. As with all versions, the major versionXmust match the module’smajor version suffix.vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdefis used when the base version isa pre-release version likevX.Y.Z-pre.vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdefis used when the base version isa release version likevX.Y.Z. For example, if the base version isv1.2.3, a pseudo-version might bev1.2.4-0.20191109021931-daa7c04131f5.
More than one pseudo-version may refer to the same commit by using differentbase versions. This happens naturally when a lower version is tagged after apseudo-version is written.
These forms give pseudo-versions two useful properties:
- Pseudo-versions with known base versions sort higher than those versions butlower than other pre-release for later versions.
- Pseudo-versions with the same base version prefix sort chronologically.
Thego command performs several checks to ensure that module authors havecontrol over how pseudo-versions are compared with other versions and thatpseudo-versions refer to revisions that are actually part of a module’scommit history.
- If a base version is specified, there must be a corresponding semantic versiontag that is an ancestor of the revision described by the pseudo-version. Thisprevents developers from bypassingminimal versionselection using a pseudo-version thatcompares higher than all tagged versions like
v1.999.999-99999999999999-daa7c04131f5. - The timestamp must match the revision’s timestamp. This prevents attackersfrom floodingmodule proxies with an unbounded numberof otherwise identical pseudo-versions. This also prevents module consumersfrom changing the relative ordering of versions.
- The revision must be an ancestor of one of the module repository’s branches ortags. This prevents attackers from referring to unapproved changes or pullrequests.
Pseudo-versions never need to be typed by hand. Many commands accepta commit hash or a branch name and will translate it into a pseudo-version(or tagged version if available) automatically. For example:
go get example.com/mod@mastergo list -m -json example.com/mod@abcd1234Major version suffixes
Starting with major version 2, module paths must have amajor versionsuffix like/v2 that matches the major version. For example, if a modulehas the pathexample.com/mod atv1.0.0, it must have the pathexample.com/mod/v2 at versionv2.0.0.
Major version suffixes implement theimport compatibilityrule:
If an old package and a new package have the same import path,the new package must be backwards compatible with the old package.
By definition, packages in a new major version of a module are not backwardscompatible with the corresponding packages in the previous major version.Consequently, starting withv2, packages need new import paths. This isaccomplished by adding a major version suffix to the module path. Since themodule path is a prefix of the import path for each package within the module,adding the major version suffix to the module path provides a distinct importpath for each incompatible version.
Major version suffixes are not allowed at major versionsv0 orv1. There isno need to change the module path betweenv0 andv1 becausev0 versionsare unstable and have no compatibility guarantee. Additionally, for mostmodules,v1 is backwards compatible with the lastv0 version; av1 versionacts as a commitment to compatibility, rather than an indication ofincompatible changes compared withv0.
As a special case, modules paths starting withgopkg.in/ must always have amajor version suffix, even atv0 andv1. The suffix must start with a dotrather than a slash (for example,gopkg.in/yaml.v2).
Major version suffixes let multiple major versions of a module coexist in thesame build. This may be necessary due to adiamond dependencyproblem. Ordinarily, ifa module is required at two different versions by transitive dependencies, thehigher version will be used. However, if the two versions are incompatible,neither version will satisfy all clients. Since incompatible versions must havedifferent major version numbers, they must also have different module paths dueto major version suffixes. This resolves the conflict: modules with distinctsuffixes are treated as separate modules, and their packages—even packages insame subdirectory relative to their module roots—are distinct.
Many Go projects released versions atv2 or higher without using a majorversion suffix before migrating to modules (perhaps before modules were evenintroduced). These versions are annotated with a+incompatible build tag (forexample,v2.0.0+incompatible). SeeCompatibility with non-modulerepositories for more information.
Resolving a package to a module
When thego command loads a package using apackagepath, it needs to determine which module provides thepackage.
Thego command starts by searching thebuild list formodules with paths that are prefixes of the package path. For example, if thepackageexample.com/a/b is imported, and the moduleexample.com/a is in thebuild list, thego command will check whetherexample.com/a contains thepackage, in the directoryb. At least one file with the.go extension mustbe present in a directory for it to be considered a package.Buildconstraints are not applied for thispurpose. If exactly one module in the build list provides the package, thatmodule is used. If no modules provide the package or if two or more modulesprovide the package, thego command reports an error. The-mod=mod flaginstructs thego command to attempt to find new modules providing missingpackages and to updatego.mod andgo.sum. Thego get andgo mod tidy commands do this automatically.
When thego command looks up a new module for a package path, it checks theGOPROXY environment variable, which is a comma-separated list of proxy URLs orthe keywordsdirect oroff. A proxy URL indicates thego command shouldcontact amodule proxy using theGOPROXYprotocol.direct indicates that thego command shouldcommunicate with a version control system.off indicates that nocommunication should be attempted. TheGOPRIVATE andGONOPROXYenvironmentvariables can also be used to control this behavior.
For each entry in theGOPROXY list, thego command requests the latestversion of each module path that might provide the package (that is, each prefixof the package path). For each successfully requested module path, thegocommand will download the module at the latest version and check whether themodule contains the requested package. If one or more modules contain therequested package, the module with the longest path is used. If one or moremodules are found but none contain the requested package, an error isreported. If no modules are found, thego command tries the next entry in theGOPROXY list. If no entries are left, an error is reported.
For example, suppose thego command is looking for a module that provides thepackagegolang.org/x/net/html, andGOPROXY is set tohttps://corp.example.com,https://proxy.golang.org. Thego command may makethe following requests:
- To
https://corp.example.com/(in parallel):- Request for latest version of
golang.org/x/net/html - Request for latest version of
golang.org/x/net - Request for latest version of
golang.org/x - Request for latest version of
golang.org
- Request for latest version of
- To
https://proxy.golang.org/, if all requests tohttps://corp.example.com/have failed with 404 or 410:- Request for latest version of
golang.org/x/net/html - Request for latest version of
golang.org/x/net - Request for latest version of
golang.org/x - Request for latest version of
golang.org
- Request for latest version of
After a suitable module has been found, thego command will add a newrequirement with the new module’s path and version tothe main module’sgo.mod file. This ensures that when the same package isloaded in the future, the same module will be used at the same version. If theresolved package is not imported by a package in the main module, the newrequirement will have an// indirect comment.
go.mod files
A module is defined by a UTF-8 encoded text file namedgo.mod in its rootdirectory. Thego.mod file is line-oriented. Each line holds a singledirective, made up of a keyword followed by arguments. For example:
module example.com/my/thinggo 1.23.0require example.com/other/thing v1.0.2require example.com/new/thing/v2 v2.3.4exclude example.com/old/thing v1.2.3replace example.com/bad/thing v1.4.5 => example.com/good/thing v1.4.5retract [v1.9.0, v1.9.5]The leading keyword can be factored out of adjacent lines to create a block,like in Go imports.
require ( example.com/new/thing/v2 v2.3.4 example.com/old/thing v1.2.3)Thego.mod file is designed to be human readable and machine writable. Thego command provides several subcommands that changego.mod files. Forexample,go get can upgrade or downgrade specific dependencies.Commands that load the module graph willautomaticallyupdatego.mod when needed.go mod edit can perform low-level edits. Thegolang.org/x/mod/modfilepackage can be used by Go programs to make the same changes programmatically.
Ago.mod file is required for themain module, and foranyreplacement module specified with a local file path.However, a module that lacks an explicitgo.mod file may still berequired as a dependency, or used as a replacementspecified with a module path and version; seeCompatibility with non-modulerepositories.
Lexical elements
When ago.mod file is parsed, its content is broken into a sequence of tokens.There are several kinds of tokens: whitespace, comments, punctuation,keywords, identifiers, and strings.
White space consists of spaces (U+0020), tabs (U+0009), carriage returns(U+000D), and newlines (U+000A). White space characters other than newlines haveno effect except to separate tokens that would otherwise be combined. Newlinesare significant tokens.
Comments start with// and run to the end of a line./* */ comments arenot allowed.
Punctuation tokens include(,), and=>.
Keywords distinguish different kinds of directives in ago.mod file. Allowedkeywords aremodule,go,require,replace,exclude, andretract.
Identifiers are sequences of non-whitespace characters, such as module pathsor semantic versions.
Strings are quoted sequences of characters. There are two kinds of strings:interpreted strings beginning and ending with quotation marks (", U+0022) andraw strings beginning and ending with grave accents (`,U+0060). Interpreted strings may contain escape sequences consisting of abackslash (\, U+005C) followed by another character. An escaped quotationmark (\") does not terminate an interpreted string. The unquoted valueof an interpreted string is the sequence of characters between quotationmarks with each escape sequence replaced by the character following thebackslash (for example,\" is replaced by",\n is replaced byn).In contrast, the unquoted value of a raw string is simply the sequence ofcharacters between grave accents; backslashes have no special meaning withinraw strings.
Identifiers and strings are interchangeable in thego.mod grammar.
Module paths and versions
Most identifiers and strings in ago.mod file are either module paths orversions.
A module path must satisfy the following requirements:
- The path must consist of one or more path elements separated by slashes(
/, U+002F). It must not begin or end with a slash. - Each path element is a non-empty string made of up ASCII letters, ASCIIdigits, and limited ASCII punctuation (
-,.,_, and~). - A path element may not begin or end with a dot (
., U+002E). - The element prefix up to the first dot must not be a reserved file name onWindows, regardless of case (
CON,com1,NuL, and so on). - The element prefix up to the first dot must not end with a tilde followed byone or more digits (like
EXAMPL~1.COM).
If the module path appears in arequire directive and is not replaced, orif the module paths appears on the right side of areplace directive,thego command may need to download modules with that path, and someadditional requirements must be satisfied.
- The leading path element (up to the first slash, if any), by convention adomain name, must contain only lower-case ASCII letters, ASCII digits, dots(
., U+002E), and dashes (-, U+002D); it must contain at least one dot andcannot start with a dash. - For a final path element of the form
/vNwhereNlooks numeric (ASCIIdigits and dots),Nmust not begin with a leading zero, must not be/v1,and must not contain any dots.- For paths beginning with
gopkg.in/, this requirement is replaced by arequirement that the path follow thegopkg.in service’sconventions.
- For paths beginning with
Versions ingo.mod files may becanonical ornon-canonical.
A canonical version starts with the letterv, followed by a semantic versionfollowing theSemantic Versioning 2.0.0specification. SeeVersions for more information.
Most other identifiers and strings may be used as non-canonical versions, thoughthere are some restrictions to avoid problems with file systems, repositories,andmodule proxies. Non-canonical versions are onlyallowed in the main module’sgo.mod file. Thego command will attempt toreplace each non-canonical version with an equivalent canonical version when itautomaticallyupdates thego.mod file.
In places where a module path is associated with a version (as inrequire,replace, andexclude directives), the final path element must be consistentwith the version. SeeMajor version suffixes.
Grammar
go.mod syntax is specified below using Extended Backus-Naur Form (EBNF).See theNotation section in the Go Language Specificationfor details on EBNF syntax.
GoMod = { Directive } .Directive = ModuleDirective | GoDirective | ToolDirective | IgnoreDirective | RequireDirective | ExcludeDirective | ReplaceDirective | RetractDirective .Newlines, identifiers, and strings are denoted withnewline,ident, andstring, respectively.
Module paths and versions are denoted withModulePath andVersion.
ModulePath = ident | string . /* see restrictions above */Version = ident | string . /* see restrictions above */module directive
Amodule directive defines the main module’spath. Ago.mod file must contain exactly onemodule directive.
ModuleDirective = "module" ( ModulePath | "(" newline ModulePath newline ")" ) newline .Example:
module golang.org/x/netDeprecation
A module can be marked as deprecated in a block of comments containing thestringDeprecated: (case-sensitive) at the beginning of a paragraph. Thedeprecation message starts after the colon and runs to the end of the paragraph.The comments may appear immediately before themodule directive or afterwardon the same line.
Example:
// Deprecated: use example.com/mod/v2 instead.module example.com/modSince Go 1.17,go list -m -u checks for information on alldeprecated modules in thebuild list.go getchecks for deprecated modules needed to build packages named on the commandline.
When thego command retrieves deprecation information for a module, it loadsthego.mod file from the version matching the@latestversionquery without consideringretractions orexclusions. Thego command loads the list ofretracted versions from the samego.mod file.
To deprecate a module, an author may add a// Deprecated: comment and tag anew release. The author may change or remove the deprecation message in a higherrelease.
A deprecation applies to all minor versions of a module. Major versions higherthanv2 are considered separate modules for this purpose, since theirmajorversion suffixes give them distinct module paths.
Deprecation messages are intended to inform users that the module is no longersupported and to provide migration instructions, for example, to the latestmajor version. Individual minor and patch versions cannot be deprecated;retract may be more appropriate for that.
go directive
Ago directive indicates that a module was written assuming the semantics of agiven version of Go. The version must be a validGo version,such as1.14,1.21rc1, or1.23.0.
Thego directive sets the minimum version of Go required to use this module.Before Go 1.21, the directive was advisory only; now it is a mandatory requirement:Go toolchains refuse to use modules declaring newer Go versions.
Thego directive is an input into selecting which Go toolchain to run.See “Go toolchains” for details.
Thego directive affects use of new language features:
- For packages within the module, the compiler rejects use of language featuresintroduced after the version specified by the
godirective. For example, ifa module has the directivego 1.12, its packages may not use numericliterals like1_000_000, which were introduced in Go 1.13. - If an older Go version builds one of the module’s packages and encounters acompile error, the error notes that the module was written for a newer Goversion. For example, suppose a module has
go 1.13and a package uses thenumeric literal1_000_000. If that package is built with Go 1.12, thecompiler notes that the code is written for Go 1.13.
Thego directive also affects the behavior of thego command:
- At
go 1.14or higher, automaticvendoring may be enabled.If the filevendor/modules.txtis present and consistent withgo.mod,there is no need to explicitly use the-mod=vendorflag. - At
go 1.16or higher, theallpackage pattern matches only packagestransitively imported by packages and tests in themainmodule. This is the same set of packages retained bygo mod vendorsince modules were introduced. In lowerversions,allalso includes tests of packages imported by packages inthe main module, tests of those packages, and so on. - At
go 1.17or higher:- The
go.modfile includes an explicitrequiredirective for each module that provides any packagetransitively imported by a package or test in the main module. (Atgo 1.16and lower, anindirect dependency isincluded only ifminimal version selectionwould otherwise select a different version.) This extra information enablesmodule graph pruning andlazy moduleloading. - Because there may be many more
// indirectdependencies than in previousgoversions, indirect dependencies are recorded in a separate blockwithin thego.modfile. go mod vendoromitsgo.modandgo.sumfiles for vendoreddependencies. (That allows invocations of thegocommand withinsubdirectories ofvendorto identify the correct main module.)go mod vendorrecords thegoversion from each dependency’sgo.modfile invendor/modules.txt.
- The
- At
go 1.21or higher:- The
goline declares a required minimum version of Go to use with this module. - The
goline must be greater than or equal to thegoline of all dependencies. - The
gocommand no longer attempts to maintain compatibility with the previous older version of Go. - The
gocommand is more careful about keeping checksums ofgo.modfiles in thego.sumfile.
- The
Ago.mod file may contain at most onego directive. Most commands will add ago directive with the current Go version if one is not present.
If thego directive is missing,go 1.16 is assumed.
GoDirective = "go" GoVersion newline .GoVersion = string | ident . /* valid release version; see above */Example:
go 1.23.0toolchain directive
Atoolchain directive declares a suggested Go toolchain to use with a module.The suggested Go toolchain’s version cannot be less than the required Go versiondeclared in thego directive.Thetoolchain directiveonly has an effect when the module is the main module and the default toolchain’sversion is less than the suggested toolchain’s version.
For reproducibility, thego command writes its own toolchain name in atoolchain line any timeit is updating thego version in thego.mod file (usually duringgo get).
For details, see “Go toolchains”.
ToolchainDirective = "toolchain" ToolchainName newline .ToolchainName = string | ident . /* valid toolchain name; see “Go toolchains” */Example:
toolchain go1.21.0godebug directive
Agodebug directive declares a singleGODEBUG settingto apply when this module is the main module.There can be more than one such line, and they can be factored.It is an error for the main module to name a GODEBUG key that does not exist.The effect ofgodebug key=value is as if every main package being compiledcontained a source file that listed//go:debug key=value.
GodebugDirective = "godebug" ( GodebugSpec | "(" newline { GodebugSpec } ")" newline ) .GodebugSpec = GodebugKey "=" GodebugValue newline.GodebugKey = GodebugChar { GodebugChar }.GodebugValue = GodebugChar { GodebugChar }.GodebugChar = any non-space character except , " ` ' (comma and quotes).Example:
godebug default=go1.21godebug ( panicnil=1 asynctimerchan=0)require directive
Arequire directive declares a minimum required version of a given moduledependency. For each required module version, thego command loads thego.mod file for that version and incorporates the requirements from thatfile. Once all requirements have been loaded, thego command resolves themusingminimal version selection (MVS) to producethebuild list.
Thego command automatically adds// indirect comments for somerequirements. An// indirect comment indicates that no package from therequired module is directly imported by any package in themainmodule.
If thego directive specifiesgo 1.16 or lower, thegocommand adds an indirect requirement when the selected version of a module ishigher than what is already implied (transitively) by the main module’s otherdependencies. That may occur because of an explicit upgrade (go get -u ./...),removal of some other dependency that previously imposed the requirement (go mod tidy), or a dependency that imports a package without a correspondingrequirement in its owngo.mod file (such as a dependency that lacks ago.modfile altogether).
Atgo 1.17 and above, thego command adds an indirect requirement for eachmodule that provides any package imported (evenindirectly) by a package or test in the main moduleor passed as an argument togo get. These more comprehensive requirementsenablemodule graph pruning andlazy moduleloading.
RequireDirective = "require" ( RequireSpec | "(" newline { RequireSpec } ")" newline ) .RequireSpec = ModulePath Version newline .Example:
require golang.org/x/net v1.2.3require ( golang.org/x/crypto v1.4.5 // indirect golang.org/x/text v1.6.7)tool directive
Atool directive adds a package as a dependency of the current module. It alsomakes it available to run withgo tool when the current working directory iswithin this module, or within a workspace that contains this module.
If the tool package is not in the current module, arequiredirective must be present that specifies the version of the tool to use.
Thetool meta-pattern resolves to the list of tools defined in the current module’sgo.mod, or in workspace mode to the union of all tools defined in all modules in theworkspace.
ToolDirective = "tool" ( ToolSpec | "(" newline { ToolSpec } ")" newline ) .ToolSpec = ModulePath newline .Example:
tool golang.org/x/tools/cmd/stringertool ( example.com/module/cmd/a example.com/module/cmd/b)ignore directive
Anignore directive will cause the go command ignore the slash-separateddirectory paths, and any files or directories recursively contained in them,when matching package patterns.
If the path starts with./, the path is interpreted relative to themodule root directory, and that directory and any directories or filesrecursively contained in it will be ignored when matching package patterns.
Otherwise, any directories with the path at any depth in the module, andany directories or files recursively contained in them will be ignored.
IgnoreDirective = "ignore" ( IgnoreSpec | "(" newline { IgnoreSpec } ")" newline ) .IgnoreSpec = RelativeFilePath newline .RelativeFilePath = /* slash-separated relative file path */ .Example
ignore ./node_modulesignore ( static content/html ./third_party/javascript)exclude directive
Anexclude directive prevents a module version from being loaded by thegocommand.
Since Go 1.16, if a version referenced by arequire directive in anygo.modfile is excluded by anexclude directive in the main module’sgo.mod file,the requirement is ignored. This may cause commands likego getandgo mod tidy to add new requirements on higher versionstogo.mod, with an// indirect comment if appropriate.
Before Go 1.16, if an excluded version was referenced by arequire directive,thego command listed available versions for the module (as shown withgo list -m -versions) and loaded the next higher non-excluded versioninstead. This could result in non-deterministic version selection, since thenext higher version could change over time. Both release and pre-releaseversions were considered for this purpose, but pseudo-versions were not. Ifthere were no higher versions, thego command reported an error.
exclude directives only apply in the main module’sgo.mod file and areignored in other modules. SeeMinimal versionselection for details.
ExcludeDirective = "exclude" ( ExcludeSpec | "(" newline { ExcludeSpec } ")" newline ) .ExcludeSpec = ModulePath Version newline .Example:
exclude golang.org/x/net v1.2.3exclude ( golang.org/x/crypto v1.4.5 golang.org/x/text v1.6.7)replace directive
Areplace directive replaces the contents of a specific version of a module,or all versions of a module, with contents found elsewhere. The replacementmay be specified with either another module path and version, or aplatform-specific file path.
If a version is present on the left side of the arrow (=>), only that specificversion of the module is replaced; other versions will be accessed normally.If the left version is omitted, all versions of the module are replaced.
If the path on the right side of the arrow is an absolute or relative path(beginning with./ or../), it is interpreted as the local file path to thereplacement module root directory, which must contain ago.mod file. Thereplacement version must be omitted in this case.
If the path on the right side is not a local path, it must be a valid modulepath. In this case, a version is required. The same module version must notalso appear in the build list.
Regardless of whether a replacement is specified with a local path or modulepath, if the replacement module has ago.mod file, itsmodule directivemust match the module path it replaces.
replace directives only apply in the main module’sgo.mod fileand are ignored in other modules. SeeMinimal versionselection for details.
If there are multiple main modules, all main modules’go.modfiles apply. Conflictingreplace directives across mainmodules are disallowed, and must be removed or overridden inareplace in thego.work file.
Note that areplace directive alone does not add a module to themodulegraph. Arequire directive thatrefers to a replaced module version is also needed, either in the main module’sgo.mod file or a dependency’sgo.mod file. Areplace directive has noeffect if the module version on the left side is not required.
ReplaceDirective = "replace" ( ReplaceSpec | "(" newline { ReplaceSpec } ")" newline ) .ReplaceSpec = ModulePath [ Version ] "=>" FilePath newline | ModulePath [ Version ] "=>" ModulePath Version newline .FilePath = /* platform-specific relative or absolute file path */Example:
replace golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5replace ( golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5 golang.org/x/net => example.com/fork/net v1.4.5 golang.org/x/net v1.2.3 => ./fork/net golang.org/x/net => ./fork/net)retract directive
Aretract directive indicates that a version or range of versions of themodule defined bygo.mod should not be depended upon. Aretract directive isuseful when a version was published prematurely or a severe problem wasdiscovered after the version was published. Retracted versions should remainavailable in version control repositories and onmoduleproxies to ensure that builds that depend on them are notbroken. The wordretract is borrowed from academic literature: a retractedresearch paper is still available, but it has problems and should not be thebasis of future work.
When a module version is retracted, users will not upgrade to it automaticallyusinggo get,go mod tidy, or othercommands. Builds that depend on retracted versions should continue to work, butusers will be notified of retractions when they check for updates withgo list -m -u or update a related module withgo get.
To retract a version, a module author should add aretract directive togo.mod, then publish a new version containing that directive. The new versionmust be higher than other release or pre-release versions; that is, the@latestversion query should resolve to the new versionbefore retractions are considered. Thego command loads and appliesretractions from the version shown bygo list -m -retracted $modpath@latest(where$modpath is the module path).
Retracted versions are hidden from the version list printed bygo list -m -versions unless the-retracted flag is used. Retractedversions are excluded when resolving version queries like@>=v1.2.3 or@latest.
A version containing retractions may retract itself. If the highest releaseor pre-release version of a module retracts itself, the@latest queryresolves to a lower version after retracted versions are excluded.
As an example, consider a case where the author of moduleexample.com/mpublishes versionv1.0.0 accidentally. To prevent users from upgrading tov1.0.0, the author can add tworetract directives togo.mod, then tagv1.0.1 with the retractions.
retract ( v1.0.0 // Published accidentally. v1.0.1 // Contains retractions only.)When a user runsgo get example.com/m@latest, thego command readsretractions fromv1.0.1, which is now the highest version. Bothv1.0.0 andv1.0.1 are retracted, so thego command will upgrade (or downgrade!) tothe next highest version, perhapsv0.9.5.
retract directives may be written with either a single version (likev1.0.0)or with a closed interval of versions with an upper and lower bound, delimited by[ and] (like[v1.1.0, v1.2.0]). A single version is equivalent to aninterval where the upper and lower bound are the same. Like other directives,multipleretract directives may be grouped together in a block delimited by( at the end of a line and) on its own line.
Eachretract directive should have a comment explaining the rationale for theretraction, though this is not mandatory. Thego command may display rationalecomments in warnings about retracted versions and ingo list output. Arationale comment may be written immediately above aretract directive(without a blank line in between) or afterward on the same line. If a commentappears above a block, it applies to allretract directives within the blockthat don’t have their own comments. A rationale comment may span multiple lines.
RetractDirective = "retract" ( RetractSpec | "(" newline { RetractSpec } ")" newline ) .RetractSpec = ( Version | "[" Version "," Version "]" ) newline .Examples:
- Retracting all versions between
v1.0.0andv1.9.9:
retract v1.0.0retract [v1.0.0, v1.9.9]retract ( v1.0.0 [v1.0.0, v1.9.9])- Returning to unversioned after prematurely released a version
v1.0.0:
retract [v0.0.0, v1.0.1] // assuming v1.0.1 contains this retraction.- Wiping out a module including all pseudo-versions and tagged versions:
retract [v0.0.0-0, v0.15.2] // assuming v0.15.2 contains this retraction.Theretract directive was added in Go 1.16. Go 1.15 and lower will report anerror if aretract directive is written in themainmodule’sgo.mod file and will ignoreretract directivesingo.mod files of dependencies.
Automatic updates
Most commands report an error ifgo.mod is missing information or doesn’taccurately reflect reality. Thego get andgo mod tidy commands may be used to fix most of theseproblems. Additionally, the-mod=mod flag may be used with most module-awarecommands (go build,go test, and so on) to instruct thego command tofix problems ingo.mod andgo.sum automatically.
For example, consider thisgo.mod file:
module example.com/Mgo 1.23.0require ( example.com/A v1 example.com/B v1.0.0 example.com/C v1.0.0 example.com/D v1.2.3 example.com/E dev)exclude example.com/D v1.2.3The update triggered with-mod=mod rewrites non-canonical version identifierstocanonical semver form, soexample.com/A’sv1becomesv1.0.0, andexample.com/E’sdev becomes the pseudo-version for thelatest commit on thedev branch, perhapsv0.0.0-20180523231146-b3f5c0f6e5f1.
The update modifies requirements to respect exclusions, so the requirement onthe excludedexample.com/D v1.2.3 is updated to use the next available versionofexample.com/D, perhapsv1.2.4 orv1.3.0.
The update removes redundant or misleading requirements. For example, ifexample.com/A v1.0.0 itself requiresexample.com/B v1.2.0 andexample.com/C v1.0.0, thengo.mod’s requirement ofexample.com/B v1.0.0 is misleading(superseded byexample.com/A’s need forv1.2.0), and its requirement ofexample.com/C v1.0.0 is redundant (implied byexample.com/A’s need for thesame version), so both will be removed. If the main module contains packagesthat directly import packages fromexample.com/B orexample.com/C, then therequirements will be kept but updated to the actual versions being used.
Finally, the update reformats thego.mod in a canonical formatting, sothat future mechanical changes will result in minimal diffs. Thego commandwill not updatego.mod if only formatting changes are needed.
Because the module graph defines the meaning of import statements, any commandsthat load packages also usego.mod and can therefore update it, includinggo build,go get,go install,go list,go test,go mod tidy.
In Go 1.15 and lower, the-mod=mod flag was enabled by default, so updateswere performed automatically. Since Go 1.16, thego command acts asif-mod=readonly were set instead: if any changes togo.mod are needed,thego command reports an error and suggests a fix.
Minimal version selection (MVS)
Go uses an algorithm calledMinimal version selection (MVS) to selecta set of module versions to use when building packages. MVS is described indetail inMinimal Version Selection byRuss Cox.
Conceptually, MVS operates on a directed graph of modules, specified withgo.mod files. Each vertex in the graph represents amodule version. Each edge represents a minimum required version of a dependency,specified using arequiredirective. The graph may be modified byexcludeandreplace directives in thego.mod file(s) of the mainmodule(s) and byreplace directives in thego.work file.
MVS produces thebuild list as output, the list of moduleversions used for a build.
MVS starts at the main modules (special vertices in the graph that have noversion) and traverses the graph, tracking the highest required version of eachmodule. At the end of the traversal, the highest required versions comprise thebuild list: they are the minimum versions that satisfy all requirements.
The build list may be inspected with the commandgo list -m all. Unlike other dependency management systems, the build list isnot saved in a “lock” file. MVS is deterministic, and the build list doesn’tchange when new versions of dependencies are released, so MVS is used to computeit at the beginning of every module-aware command.
Consider the example in the diagram below. The main module requires module Aat version 1.2 or higher and module B at version 1.2 or higher. A 1.2 and B 1.2require C 1.3 and C 1.4, respectively. C 1.3 and C 1.4 both require D 1.2.
MVS visits and loads thego.mod file for each of the module versionshighlighted in blue. At the end of the graph traversal, MVS returns a build listcontaining the bolded versions: A 1.2, B 1.2, C 1.4, and D 1.2. Note that higherversions of B and D are available but MVS does not select them, since nothingrequires them.
Replacement
The content of a module (including itsgo.mod file) may be replaced using areplace directive in a main module’sgo.mod fileor a workspace’sgo.work file. Areplace directive may apply to a specificversion of a module or to all versions of a module.
Replacements change the module graph, since a replacement module may havedifferent dependencies than replaced versions.
Consider the example below, where C 1.4 has been replaced with R. R depends on D1.3 instead of D 1.2, so MVS returns a build list containing A 1.2, B 1.2, C 1.4(replaced with R), and D 1.3.
Exclusion
A module may also be excluded at specific versions using anexcludedirective in the main module’sgo.mod file.
Exclusions also change the module graph. When a version is excluded, it isremoved from the module graph, and requirements on it are redirected to thenext higher version.
Consider the example below. C 1.3 has been excluded. MVS will act as if A 1.2required C 1.4 (the next higher version) instead of C 1.3.
Upgrades
Thego get command may be used to upgrade a set of modules. Toperform an upgrade, thego command changes the module graph before running MVSby adding edges from visited versions to upgraded versions.
Consider the example below. Module B may be upgraded from 1.2 to 1.3, C may beupgraded from 1.3 to 1.4, and D may be upgraded from 1.2 to 1.3.
Upgrades (and downgrades) may add or remove indirect dependencies. In this case,E 1.1 and F 1.1 appear in the build list after the upgrade, since E 1.1 isrequired by B 1.3.
To preserve upgrades, thego command updates the requirements ingo.mod. Itwill change the requirement on B to version 1.3. It will also add requirementson C 1.4 and D 1.3 with// indirect comments, since those versions would notbe selected otherwise.
Downgrade
Thego get command may also be used to downgrade a set ofmodules. To perform a downgrade, thego command changes the module graph byremoving versions above the downgraded versions. It also removes versions ofother modules that depend on removed versions, since they may not be compatiblewith the downgraded versions of their dependencies. If the main module requiresa module version removed by downgrading, the requirement is changed to aprevious version that has not been removed. If no previous version is available,the requirement is dropped.
Consider the example below. Suppose that a problem was found with C 1.4, so wedowngrade to C 1.3. C 1.4 is removed from the module graph. B 1.2 is alsoremoved, since it requires C 1.4 or higher. The main module’s requirement on Bis changed to 1.1.
go get can also remove dependencies entirely, using an@nonesuffix after an argument. This works similarly to a downgrade. All versionsof the named module are removed from the module graph.
Module graph pruning
If the main module is atgo 1.17 or higher, themodulegraph used forminimal versionselection includes only theimmediaterequirements for each module dependency that specifiesgo 1.17 or higher inits owngo.mod file, unless that version of the module is also (transitively)required by someother dependency atgo 1.16 or below. (Thetransitivedependencies ofgo 1.17 dependencies arepruned out of the module graph.)
Since ago 1.17go.mod file includes arequiredirective for every dependency needed to build anypackage or test in that module, the pruned module graph includes all of thedependencies needed togo build orgo test the packages in any dependencyexplicitly required by themain module. A module that isnot needed to build any package or test in a given module cannot affect therun-time behavior of its packages, so the dependencies that are pruned out ofthe module graph would only cause interference between otherwise-unrelatedmodules.
Modules whose requirements have been pruned out still appear in the module graphand are still reported bygo list -m all: theirselectedversions are known and well-defined, and packages canbe loaded from those modules (for example, as transitive dependencies of testsloaded from other modules). However, since thego command cannot easilyidentify which dependencies of these modules are satisfied, the arguments togo build andgo test cannot include packages from modules whose requirementshave been pruned out.go get promotes the module containing eachnamed package to an explicit dependency, allowinggo build orgo test to beinvoked on that package.
Because Go 1.16 and earlier did not support module graph pruning, the fulltransitive closure of dependencies — including transitivego 1.17dependencies — is still included for each module that specifiesgo 1.16 orlower. (Atgo 1.16 and below, thego.mod file includes onlydirect dependencies, so a much larger graph must beloaded to ensure that all indirect dependencies are included.)
Thego.sum file recorded bygo mod tidy fora module by default includes checksums needed by the Go versionone below theversion specified in itsgo directive. So ago 1.17module includes checksums needed for the full module graph loaded by Go 1.16,but ago 1.18 module will include only the checksums needed for the prunedmodule graph loaded by Go 1.17. The-compat flag can be used to override thedefault version (for example, to prune thego.sum file more aggressively in ago 1.17 module).
Seethe design document for more detail.
Lazy module loading
The more comprehensive requirements added for module graph pruning also enableanother optimization when working within a module. If the main module is atgo 1.17 or higher, thego command avoids loading the complete module graphuntil (and unless) it is needed. Instead, it loads only the main module’sgo.mod file, then attempts to load the packages to be built using only thoserequirements. If a package to be imported (for example, a dependency of a testfor a package outside the main module) is not found among those requirements,then the rest of the module graph is loaded on demand.
If all imported packages can be found without loading the module graph, thego command then loads thego.mod files foronly the modules containingthose packages, and their requirements are checked against the requirements ofthe main module to ensure that they are locally consistent. (Inconsistencies canarise due to version-control merges, hand-edits, and changes in modules thathave beenreplaced using local filesystem paths.)
Workspaces
Aworkspace is a collection of modules on disk that are used asthe main modules when runningminimal version selection (MVS).
A workspace can be declared in ago.work file that specifiesrelative paths to the module directories of each of the modules in the workspace.When nogo.work file exists, the workspace consists of the single modulecontaining the current directory.
Mostgo subcommands that work with modulesoperate on the set of modules determined by the current workspace.go mod init,go mod why,go mod edit,go mod tidy,go mod vendor,andgo get always operate on a single main module.
A command determines whether it is in a workspace context by first examiningtheGOWORK environment variable. IfGOWORK is set tooff, the command will bein a single-module context. If it is empty or not provided, the commandwill search the current working directory, and then successive parent directories,for a filego.work. If a file is found, the command will operate in theworkspace it defines; otherwise, the workspace will include only the modulecontaining the working directory.IfGOWORK names a path to an existing file that ends in .work,workspace mode will be enabled. Any other value is an error. You can use thego env GOWORK command to determine whichgo.work file thego commandis using.go env GOWORK will be empty if thego command is not in workspacemode.
go.work files
A workspace is defined by a UTF-8 encoded text file namedgo.work. Thego.work file is line oriented. Each line holds a single directive, made up ofa keyword followed by arguments. For example:
go 1.23.0use ./my/first/thinguse ./my/second/thingreplace example.com/bad/thing v1.4.5 => example.com/good/thing v1.4.5As ingo.mod files, a leading keyword can be factored out of adjacent linesto create a block.
use ( ./my/first/thing ./my/second/thing)Thego command provides several subcommands for manipulatinggo.work files.go work init creates newgo.work files.go work use adds module directories tothego.work file.go work edit performs low-leveledits. Thegolang.org/x/mod/modfilepackage can be used by Go programs to make the same changes programmatically.
The go command will maintain ago.work.sum file that keeps track of hashes used by the workspacethat are not in collective workspace modules’ go.sum files.
It is generally inadvisable to commit go.work files into version controlsystems, for two reasons:
- A checked-in
go.workfile might override a developer’s owngo.workfilefrom a parent directory, causing confusion when theirusedirectives don’tapply. - A checked-in
go.workfile may cause a continuous integration (CI) system toselect and thus test the wrong versions of a module’s dependencies. CI systemsshould generally not be allowed to use thego.workfile so that they can testthe behavior of the module as it would be used when required by other modules,where ago.workfile within the module has no effect.
That said, there are some cases where committing ago.work file makes sense.For example, when the modules in a repository are developed exclusively witheach other but not together with external modules, there may not be a reason thedeveloper would want to use a different combination of modules in a workspace.In that case, the module author should ensure the individual modules are testedand released properly.
Lexical elements
Lexical elements ingo.work files are defined in exactly the same wayas forgo.mod files.
Grammar
go.work syntax is specified below using Extended Backus-Naur Form (EBNF).See theNotation section in the Go Language Specificationfor details on EBNF syntax.
GoWork = { Directive } .Directive = GoDirective | ToolchainDirective | UseDirective | ReplaceDirective .Newlines, identifiers, and strings are denoted withnewline,ident, andstring, respectively.
Module paths and versions are denoted withModulePath andVersion.Module paths and versions are specified in exactly the same wayas forgo.mod files.
ModulePath = ident | string . /* see restrictions above */Version = ident | string . /* see restrictions above */go directive
Ago directive is required in a validgo.work file. The version mustbe a valid Go release version: a positiveinteger followed by a dot and a non-negative integer (for example,1.18,1.19).
Thego directive indicates the go toolchain version with which thego.work file is intended to work. If changes are made to thego.workfile format, future versions of the toolchain will interpret the fileaccording to its indicated version.
Ago.work file may contain at most onego directive.
GoDirective = "go" GoVersion newline .GoVersion = string | ident . /* valid release version; see above */Example:
go 1.23.0toolchain directive
Atoolchain directive declares a suggested Go toolchain to use in a workspace.It only has an effect when the default toolchainis older than the suggested toolchain.
For details, see “Go toolchains”.
ToolchainDirective = "toolchain" ToolchainName newline .ToolchainName = string | ident . /* valid toolchain name; see “Go toolchains” */Example:
toolchain go1.21.0godebug directive
Agodebug directive declares a singleGODEBUG settingto apply when working in this workspace.The syntax and effect is the same as thego.mod file’sgodebug directive.When a workspace is in use,godebug directives ingo.mod files are ignored.
use directive
Ause adds a module on disk to the set of main modules in a workspace.Its argument is a relative path to the directory containing the module’sgo.mod file. Ause directive does not add modules contained insubdirectories of its argument directory. Those modules may be added bythe directory containing theirgo.mod file in separateuse directives.
UseDirective = "use" ( UseSpec | "(" newline { UseSpec } ")" newline ) .UseSpec = FilePath newline .FilePath = /* platform-specific relative or absolute file path */Example:
use ./mymod // example.com/mymoduse ( ../othermod ./subdir/thirdmod)replace directive
Similar to areplace directive in ago.mod file, areplace directive inago.work file replaces the contents of a specific version of a module,or all versions of a module, with contents found elsewhere. A wildcard replaceingo.work overrides a version-specificreplace in ago.mod file.
replace directives ingo.work files override any replaces of the samemodule or module version in workspace modules.
ReplaceDirective = "replace" ( ReplaceSpec | "(" newline { ReplaceSpec } ")" newline ) .ReplaceSpec = ModulePath [ Version ] "=>" FilePath newline | ModulePath [ Version ] "=>" ModulePath Version newline .FilePath = /* platform-specific relative or absolute file path */Example:
replace golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5replace ( golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5 golang.org/x/net => example.com/fork/net v1.4.5 golang.org/x/net v1.2.3 => ./fork/net golang.org/x/net => ./fork/net)Compatibility with non-module repositories
To ensure a smooth transition fromGOPATH to modules, thego command candownload and build packages in module-aware mode from repositories that have notmigrated to modules by adding ago.mod file.
When thego command downloads a module at a given versiondirectlyfrom a repository, it looks up a repository URL for the module path, maps theversion to a revision within the repository, then extracts an archive of therepository at that revision. If themodule’s path is equalto therepository root path, and the repositoryroot directory does not contain ago.mod file, thego command synthesizes ago.mod file in the module cache that contains amoduledirective and nothing else. Since syntheticgo.mod filesdo not containrequire directives for theirdependencies, other modules that depend on them may need additionalrequiredirectives (with// indirect comments) to ensure each dependency is fetched atthe same version on every build.
When thego command downloads a module from aproxy, it downloads thego.mod file separatelyfrom the rest of the module content. The proxy is expected to serve a syntheticgo.mod file if the original module didn’t have one.
+incompatible versions
A module released at major version 2 or higher must have a matchingmajorversion suffix on its module path. For example, if amodule is released atv2.0.0, its path must have a/v2 suffix. This allowsthego command to treat multiple major versions of a project as distinctmodules, even if they’re developed in the same repository.
The major version suffix requirement was introduced when module support wasadded to thego command, and many repositories had already tagged releaseswith major version2 or higher before that. To maintain compatibility withthese repositories, thego command adds an+incompatible suffix to versionswith major version 2 or higher without ago.mod file.+incompatibleindicates that a version is part of the same module as versions with lower majorversion numbers; consequently, thego command may automatically upgrade tohigher+incompatible versions even though it may break the build.
Consider the example requirement below:
require example.com/m v4.1.2+incompatibleThe versionv4.1.2+incompatible refers to thesemantic versiontagv4.1.2 in the repository that provides themoduleexample.com/m. The module must be in the repository root directory(that is, therepository root path must also beexample.com/m), and ago.mod file must not be present. The module may haveversions with lower major version numbers likev1.5.2, and thego commandmay upgrade automatically tov4.1.2+incompatible from those versions (seeminimal version selection (MVS) for informationon how upgrades work).
A repository that migrates to modules after versionv2.0.0 is tagged shouldusually release a new major version. In the example above, the author shouldcreate a module with the pathexample.com/m/v5 and should release versionv5.0.0. The author should also update imports of packages in the module to usethe prefixexample.com/m/v5 instead ofexample.com/m. SeeGo Modules: v2and Beyond for a more detailed example.
Note that the+incompatible suffix should not appear on a tag in a repository;a tag likev4.1.2+incompatible will be ignored. The suffix only appears inversions used by thego command. SeeMapping versions tocommits for details on the distinction between versions and tags.
Note also that the+incompatible suffix may appear onpseudo-versions. For example,v2.0.1-20200722182040-012345abcdef+incompatible may be a valid pseudo-version.
Minimal module compatibility
A module released at major version 2 or higher is required to have amajorversion suffix on itsmodulepath. The module may or may not be developed in amajorversion subdirectory within its repository.This has implications for packages that import packages within the module whenbuildingGOPATH mode.
Normally inGOPATH mode, a package is stored in a directory matching itsrepository’s root path joined with its directorywithin the repository. For example, a package in the repository with root pathexample.com/repo in the subdirectorysub would be stored in$GOPATH/src/example.com/repo/sub and would be imported asexample.com/repo/sub.
For a module with a major version suffix, one might expect to find the packageexample.com/repo/v2/sub in the directory$GOPATH/src/example.com/repo/v2/sub. This would require the module to bedeveloped in thev2 subdirectory of its repository. Thego command supportsthis but does not require it (seeMapping versions to commits).
If a module isnot developed in a major version subdirectory, then itsdirectory inGOPATH will not contain the major version suffix, and itspackages may be imported without the major version suffix. In the example above,the package would be found in the directory$GOPATH/src/example.com/repo/suband would be imported asexample.com/repo/sub.
This creates a problem for packages intended to be built in both module modeandGOPATH mode: module mode requires a suffix, whileGOPATH mode does not.
To fix this,minimal module compatibility was added in Go 1.11 andwas backported to Go 1.9.7 and 1.10.3. When an import path is resolved to adirectory inGOPATH mode:
- When resolving an import of the form
$modpath/$vn/$dirwhere:$modpathis a valid module path,$vnis a major version suffix,$diris a possibly empty subdirectory,
- If all of the following are true:
- The package
$modpath/$vn/$diris not present in any relevantvendordirectory. - A
go.modfile is present in the same directory as the importing fileor in any parent directory up to the$GOPATH/srcroot, - No
$GOPATH[i]/src/$modpath/$vn/$suffixdirectory exists (for any root$GOPATH[i]), - The file
$GOPATH[d]/src/$modpath/go.modexists (for some root$GOPATH[d]) and declares the module path as$modpath/$vn,
- The package
- Then the import of
$modpath/$vn/$diris resolved to the directory$GOPATH[d]/src/$modpath/$dir.
This rules allow packages that have been migrated to modules to import otherpackages that have been migrated to modules when built inGOPATH mode evenwhen a major version subdirectory was not used.
Module-aware commands
Mostgo commands may run inModule-aware mode orGOPATH mode. Inmodule-aware mode, thego command usesgo.mod files to find versioneddependencies, and it typically loads packages out of themodulecache, downloading modules if they are missing. InGOPATHmode, thego command ignores modules; it looks invendordirectories and inGOPATH to find dependencies.
As of Go 1.16, module-aware mode is enabled by default, regardless of whether ago.mod file is present. In lower versions, module-aware mode was enabled whenago.mod file was present in the current directory or any parent directory.
Module-aware mode may be controlled with theGO111MODULE environment variable,which can be set toon,off, orauto.
- If
GO111MODULE=off, thegocommand ignoresgo.modfiles and runs inGOPATHmode. - If
GO111MODULE=onor is unset, thegocommand runs in module-aware mode,even when nogo.modfile is present. Not all commands work without ago.modfile: seeModule commands outside a module. - If
GO111MODULE=auto, thegocommand runs in module-aware mode if ago.modfile is present in the current directory or any parent directory.In Go 1.15 and lower, this was the default behavior.go modsubcommandsandgo installwith aversion query run in module-awaremode even if nogo.modfile is present.
In module-aware mode,GOPATH no longer defines the meaning of imports during abuild, but it still stores downloaded dependencies (inGOPATH/pkg/mod; seeModule cache) and installed commands (inGOPATH/bin, unlessGOBIN is set).
Build commands
All commands that load information about packages are module-aware. Thisincludes:
go buildgo fixgo generatego installgo listgo rungo testgo vet
When run in module-aware mode, these commands usego.mod files to interpretimport paths listed on the command line or written in Go source files. Thesecommands accept the following flags, common to all module commands.
- The
-modflag controls whethergo.modmay be automatically updated andwhether thevendordirectory is used.-mod=modtells thegocommand to ignore the vendor directory and toautomatically updatego.mod, for example, when animported package is not provided by any known module.-mod=readonlytells thegocommand to ignore thevendordirectory andto report an error ifgo.modneeds to be updated.-mod=vendortells thegocommand to use thevendordirectory. In thismode, thegocommand will not use the network or the module cache.- By default, if the
goversion ingo.modis1.14orhigher and avendordirectory is present, thegocommand acts as if-mod=vendorwere used. Otherwise, thegocommand acts as if-mod=readonlywere used. go getrejects this flag as the purpose of the command is to modifydependencies, which is only allowed by-mod=mod.
- The
-modcacherwflag instructs thegocommand to create new directoriesin the module cache with read-write permissions instead of making themread-only. When this flag is used consistently (typically by settingGOFLAGS=-modcacherwin the environment or by runninggo env -w GOFLAGS=-modcacherw), the module cache may be deleted withcommands likerm -rwithout changing permissions first. Thego clean -modcachecommand may be used to delete themodule cache, whether or not-modcacherwwas used. - The
-modfile=file.modflag instructs thegocommand to read (and possiblywrite) an alternate file instead ofgo.modin the module root directory. Thefile’s name must end with.mod. A file namedgo.modmust still be presentin order to determine the module root directory, but it is not accessed. When-modfileis specified, an alternatego.sumfile is also used: its path isderived from the-modfileflag by trimming the.modextension andappending.sum.
Vendoring
When using modules, thego command typically satisfies dependencies bydownloading modules from their sources into the module cache, then loadingpackages from those downloaded copies.Vendoring may be used to allowinteroperation with older versions of Go, or to ensure that all files used for abuild are stored in a single file tree.
Thego mod vendor command constructs a directory namedvendor in themain module’s root directory containingcopies of all packages needed to build and test packages in the main module.Packages that are only imported by tests of packages outside the main module arenot included. As withgo mod tidy and other module commands,build constraints except forignore are notconsidered when constructing thevendor directory.
go mod vendor also creates the filevendor/modules.txt that contains a listof vendored packages and the module versions they were copied from. Whenvendoring is enabled, this manifest is used as a source of module versioninformation, as reported bygo list -m andgo version -m. When thego command readsvendor/modules.txt, it checksthat the module versions are consistent withgo.mod. Ifgo.mod has changedsincevendor/modules.txt was generated, thego command will report an error.go mod vendor should be run again to update thevendor directory.
If thevendor directory is present in the main module’s root directory, itwill be used automatically if thego version in the mainmodule’sgo.mod file is1.14 or higher. To explicitlyenable vendoring, invoke thego command with the flag-mod=vendor. Todisable vendoring, use the flag-mod=readonly or-mod=mod.
When vendoring is enabled,build commands likego build andgo test load packages from thevendor directory instead of accessing thenetwork or the local module cache. Thego list -m command onlyprints information about modules listed ingo.mod.go mod commands such asgo mod download andgo mod tidy do notwork differently when vendoring is enabled and will still download modules andaccess the module cache.go get also does not work differently whenvendoring is enabled.
Unlikevendoring inGOPATH mode, thegocommand ignores vendor directories in locations other than the main module’sroot directory. Additionally, since vendor directories in other modules are notused, thego command does not include vendor directories when buildingmodulezip files (but see known bugs#31562 and#37397).
go get
Usage:
go get [-d] [-t] [-u] [build flags] [packages]Examples:
# Upgrade a specific module.$ go get golang.org/x/net# Upgrade modules that provide packages imported by packages in the main module.$ go get -u ./...# Upgrade or downgrade to a specific version of a module.$ go get golang.org/x/text@v0.3.2# Update to the commit on the module's master branch.$ go get golang.org/x/text@master# Remove a dependency on a module and downgrade modules that require it# to versions that don't require it.$ go get golang.org/x/text@none# Upgrade the minimum required Go version for the main module.$ go get go# Upgrade the suggested Go toolchain, leaving the minimum Go version alone.$ go get toolchain# Upgrade to the latest patch release of the suggested Go toolchain.$ go get toolchain@patchThego get command updates module dependencies in thego.modfile for themain module, then builds andinstalls packages listed on the command line.
The first step is to determine which modules to update.go get accepts a listof packages, package patterns, and module paths as arguments. If a packageargument is specified,go get updates the module that provides the package.If a package pattern is specified (for example,all or a path with a...wildcard),go get expands the pattern to a set of packages, then updates themodules that provide the packages. If an argument names a module but not apackage (for example, the modulegolang.org/x/net has no package in its rootdirectory),go get will update the module but will not build a package. If noarguments are specified,go get acts as if. were specified (the package inthe current directory); this may be used together with the-u flag to updatemodules that provide imported packages.
Each argument may include aversion query suffix indicating thedesired version, as ingo get golang.org/x/text@v0.3.0. A version querysuffix consists of an@ symbol followed by aversion query,which may indicate a specific version (v0.3.0), a version prefix (v0.3),a branch or tag name (master), a revision (1234abcd), or one of the specialquerieslatest,upgrade,patch, ornone. If no version is given,go get uses the@upgrade query.
Oncego get has resolved its arguments to specific modules and versions,go get will add, change, or removerequire directives inthe main module’sgo.mod file to ensure the modules remain at the desiredversions in the future. Note that required versions ingo.mod files areminimum versions and may be increased automatically as new dependencies areadded. SeeMinimal version selection (MVS) fordetails on how versions are selected and conflicts are resolved by module-awarecommands.
Other modules may be upgraded when a module named on the command line is added,upgraded, or downgraded if the new version of the named module requires othermodules at higher versions. For example, suppose moduleexample.com/a isupgraded to versionv1.5.0, and that version requires moduleexample.com/bat versionv1.2.0. If moduleexample.com/b is currently required at versionv1.1.0,go get example.com/a@v1.5.0 will also upgradeexample.com/b tov1.2.0.
Other modules may be downgraded when a module named on the command line isdowngraded or removed. To continue the above example, suppose moduleexample.com/b is downgraded tov1.1.0. Moduleexample.com/a would also bedowngraded to a version that requiresexample.com/b at versionv1.1.0 orlower.
A module requirement may be removed using the version suffix@none. This is aspecial kind of downgrade. Modules that depend on the removed module will bedowngraded or removed as needed. A module requirement may be removed even if oneor more of its packages are imported by packages in the main module. In thiscase, the next build command may add a new module requirement.
If a module is needed at two different versions (specified explicitly in commandline arguments or to satisfy upgrades and downgrades),go get will report anerror.
Aftergo get has selected a new set of versions, it checks whether any newlyselected module versions or any modules providing packages named on the commandline areretracted ordeprecated.go get prints a warning for eachretracted version or deprecated module it finds.go list -m -u all may be used to check for retractions and deprecations in alldependencies.
Aftergo get updates thego.mod file, it builds the packages namedon the command line. Executables will be installed in the directory named bytheGOBIN environment variable, which defaults to$GOPATH/bin or$HOME/go/bin if theGOPATH environment variable is not set.
go get supports the following flags:
- The
-dflag tellsgo getnot to build or install packages. When-disused,go getwill only manage dependencies ingo.mod. Usinggo getwithout-dto build and install packages is deprecated (as of Go 1.17).In Go 1.18,-dwill always be enabled. - The
-uflag tellsgo getto upgrade modules providing packagesimported directly or indirectly by packages named on the command line.Each module selected by-uwill be upgraded to its latest version unlessit is already required at a higher version (a pre-release). - The
-u=patchflag (not-u patch) also tellsgo getto upgradedependencies, butgo getwill upgrade each dependency to the latest patchversion (similar to the@patchversion query). - The
-tflag tellsgo getto consider modules needed to build testsof packages named on the command line. When-tand-uare used together,go getwill update test dependencies as well. - The
-insecureflag should no longer be used. It permitsgo getto resolvecustom import paths and fetch from repositories and module proxies usinginsecure schemes such as HTTP. TheGOINSECUREenvironmentvariable provides more fine-grained control andshould be used instead.
Since Go 1.16,go install is the recommended command forbuilding and installing programs. When used with a version suffix (like@latest or@v1.4.6),go install builds packages in module-aware mode,ignoring thego.mod file in the current directory or any parent directory,if there is one.
go get is more focused on managing requirements ingo.mod. The-d flagis deprecated, and in Go 1.18, it will always be enabled.
go install
Usage:
go install [build flags] [packages]Examples:
# Install the latest version of a program,# ignoring go.mod in the current directory (if any).$ go install golang.org/x/tools/gopls@latest# Install a specific version of a program.$ go install golang.org/x/tools/gopls@v0.6.4# Install a program at the version selected by the module in the current directory.$ go install golang.org/x/tools/gopls# Install all programs in a directory.$ go install ./cmd/...Thego install command builds and installs the packages named by the pathson the command line. Executables (main packages) are installed to thedirectory named by theGOBIN environment variable, which defaults to$GOPATH/bin or$HOME/go/bin if theGOPATH environment variable is not set.Executables in$GOROOT are installed in$GOROOT/bin or$GOTOOLDIR insteadof$GOBIN. Non-executable packages are built and cached but not installed.
Since Go 1.16, if the arguments have version suffixes (like@latest or@v1.0.0),go install builds packages in module-aware mode, ignoring thego.mod file in the current directory or any parent directory if there isone. This is useful for installing executables without affecting thedependencies of the main module.
To eliminate ambiguity about which module versions are used in the build, thearguments must satisfy the following constraints:
- Arguments must be package paths or package patterns (with “
...” wildcards).They must not be standard packages (likefmt), meta-patterns (std,cmd,all,work,tool), or relative or absolute file paths. - All arguments must have the same version suffix. Different queries are notallowed, even if they refer to the same version.
- All arguments must refer to packages in the same module at the same version.
- Package path arguments must refer to
mainpackages. Pattern argumentswill only matchmainpackages. - No module is considered themain module.
- If the module containing packages named on the command line has a
go.modfile, it must not contain directives (replaceandexclude) that wouldcause it to be interpreted differently if it were the main module. - The module must not require a higher version of itself.
- Vendor directories are not used in any module. (Vendor directories are notincluded inmodule zip files, so
go installdoes notdownload them.)
- If the module containing packages named on the command line has a
SeeVersion queries for supported version query syntax.Go 1.15 and lower did not support using version queries withgo install.
If the arguments don’t have version suffixes,go install may run inmodule-aware mode orGOPATH mode, depending on theGO111MODULE environmentvariable and the presence of ago.mod file. SeeModule-awarecommands for details. If module-aware mode is enabled,go install runs in the context of the main module, which may be different from themodule containing the package being installed.
go list -m
Usage:
go list -m [-u] [-retracted] [-versions] [list flags] [modules]Example:
$ go list -m all$ go list -m -versions example.com/m$ go list -m -json example.com/m@latestThe-m flag causesgo list to list modules instead of packages. In thismode, the arguments togo list may be modules, module patterns (containing the... wildcard),version queries, or the special patternall, which matches all modules in thebuild list. If noarguments are specified, themain module is listed.
When listing modules, the-f flag still specifies a format template appliedto a Go struct, but now aModule struct:
type Module struct { Path string // module path Version string // module version Versions []string // available module versions Replace *Module // replaced by this module Time *time.Time // time version was created Update *Module // available update (with -u) Main bool // is this the main module? Indirect bool // module is only indirectly needed by main module Dir string // directory holding local copy of files, if any GoMod string // path to go.mod file describing module, if any GoVersion string // go version used in module Retracted []string // retraction information, if any (with -retracted or -u) Deprecated string // deprecation message, if any (with -u) Error *ModuleError // error loading module}type ModuleError struct { Err string // the error itself}The default output is to print the module path and then information about theversion and replacement if any. For example,go list -m all might print:
example.com/main/modulegolang.org/x/net v0.1.0golang.org/x/text v0.3.0 => /tmp/textrsc.io/pdf v0.1.1TheModule struct has aString method that formats this line of output, sothat the default format is equivalent to-f '{{.String}}'.
Note that when a module has been replaced, itsReplace field describes thereplacement module, and itsDir field is set to the replacementmodule’s source code, if present. (That is, ifReplace is non-nil, thenDiris set toReplace.Dir, with no access to the replaced source code.)
The-u flag adds information about available upgrades. When the latest versionof a given module is newer than the current one,list -u sets the module’sUpdate field to information about the newer module.list -u also printswhether the currently selected version isretractedand whether the module isdeprecated. Themodule’sString method indicates an available upgrade by formatting the newerversion in brackets after the current version. For example,go list -m -u allmight print:
example.com/main/modulegolang.org/x/old v1.9.9 (deprecated)golang.org/x/net v0.1.0 (retracted) [v0.2.0]golang.org/x/text v0.3.0 [v0.4.0] => /tmp/textrsc.io/pdf v0.1.1 [v0.1.2](For tools,go list -m -u -json all may be more convenient to parse.)
The-versions flag causeslist to set the module’sVersions field to alist of all known versions of that module, ordered according to semanticversioning, lowest to highest. The flag also changes the default output formatto display the module path followed by the space-separated version list.Retracted versions are omitted from this list unless the-retracted flagis also specified.
The-retracted flag instructslist to show retracted versions in the listprinted with the-versions flag and to consider retracted versions whenresolvingversion queries. For example,go list -m -retracted example.com/m@latest shows the highest release or pre-releaseversion of the moduleexample.com/m, even if that version is retracted.retract directives anddeprecations are loaded from thego.modfile at this version. The-retracted flag was added in Go 1.16.
The template functionmodule takes a single string argument that must be amodule path or query and returns the specified module as aModule struct. Ifan error occurs, the result will be aModule struct with a non-nilErrorfield.
go mod download
Usage:
go mod download [-x] [-json] [-reuse=old.json] [modules]Example:
$ go mod download$ go mod download golang.org/x/mod@v0.2.0Thego mod download command downloads the named modules into themodulecache. Arguments can be module paths or modulepatterns selecting dependencies of the main module orversionqueries of the formpath@version. With no arguments,download applies to all dependencies of themain module.
Thego command will automatically download modules as needed during ordinaryexecution. Thego mod download command is useful mainly for pre-filling themodule cache or for loading data to be served by amoduleproxy.
By default,download writes nothing to standard output. It prints progressmessages and errors to standard error.
The-json flag causesdownload to print a sequence of JSON objects tostandard output, describing each downloaded module (or failure), correspondingto this Go struct:
type Module struct { Path string // module path Query string // version query corresponding to this version Version string // module version Error string // error loading module Info string // absolute path to cached .info file GoMod string // absolute path to cached .mod file Zip string // absolute path to cached .zip file Dir string // absolute path to cached source root directory Sum string // checksum for path, version (as in go.sum) GoModSum string // checksum for go.mod (as in go.sum) Origin any // provenance of module Reuse bool // reuse of old module info is safe}The-x flag causesdownload to print the commandsdownload executesto standard error.
The -reuse flag accepts the name of file containing the JSON output of aprevious ‘go mod download -json’ invocation. The go command may use thisfile to determine that a module is unchanged since the previous invocationand avoid redownloading it. Modules that are not redownloaded will be markedin the new output by setting the Reuse field to true. Normally the modulecache provides this kind of reuse automatically; the -reuse flag can beuseful on systems that do not preserve the module cache.
go mod edit
Usage:
go mod edit [editing flags] [-fmt|-print|-json] [go.mod]Example:
# Add a replace directive.$ go mod edit -replace example.com/a@v1.0.0=./a# Remove a replace directive.$ go mod edit -dropreplace example.com/a@v1.0.0# Set the go version, add a requirement, and print the file# instead of writing it to disk.$ go mod edit -go=1.14 -require=example.com/m@v1.0.0 -print# Format the go.mod file.$ go mod edit -fmt# Format and print a different .mod file.$ go mod edit -print tools.mod# Print a JSON representation of the go.mod file.$ go mod edit -jsonThego mod edit command provides a command-line interface for editing andformattinggo.mod files, for use primarily by tools and scripts.go mod editreads only onego.mod file; it does not look up information about othermodules. By default,go mod edit reads and writes thego.mod file of themain module, but a different target file can be specified after the editingflags.
The editing flags specify a sequence of editing operations.
- The
-moduleflag changes the module’s path (thego.modfile’s moduleline). - The
-go=versionflag sets the expected Go language version. - The
-require=path@versionand-droprequire=pathflags add and drop arequirement on the given module path and version. Note that-requireoverrides any existing requirements onpath. These flags are mainly fortools that understand the module graph. Users should prefergo get path@versionorgo get path@none, which make othergo.modadjustments asneeded to satisfy constraints imposed by other modules. Seego get. - The
-exclude=path@versionand-dropexclude=path@versionflags add and dropan exclusion for the given module path and version. Note that-exclude=path@versionis a no-op if that exclusion already exists. - The
-replace=old[@v]=new[@v]flag adds a replacement of the given modulepath and version pair. If the@vinold@vis omitted, a replacementwithout a version on the left side is added, which applies to all versions ofthe old module path. If the@vinnew@vis omitted, the new path should bea local module root directory, not a module path. Note that-replaceoverrides any redundant replacements forold[@v], so omitting@vwill dropreplacements for specific versions. - The
-dropreplace=old[@v]flag drops a replacement of the given module pathand version pair. If the@vis provided, a replacement with the givenversion is dropped. An existing replacement without a version on the left sidemay still replace the module. If the@vis omitted, a replacement without aversion is dropped. - The
-retract=versionand-dropretract=versionflags add and drop aretraction for the given version, which may be a single version (likev1.2.3) or an interval (like[v1.1.0,v1.2.0]). Note that the-retractflag cannot add a rationale comment for theretractdirective. Rationalecomments are recommended and may be shown bygo list -m -uand othercommands. - The
-tool=pathand-droptool=pathflags add and drop atooldirectivefor the given paths. Note that this will not add necessary dependencies tothe build graph. Users should prefergo get -tool pathto add a tool, orgo get -tool path@noneto remove one.
The editing flags may be repeated. The changes are applied in the order given.
go mod edit has additional flags that control its output.
- The
-fmtflag reformats thego.modfile without making other changes.This reformatting is also implied by any other modifications that use orrewrite thego.modfile. The only time this flag is needed is if noother flags are specified, as ingo mod edit -fmt. - The
-printflag prints the finalgo.modin its text format instead ofwriting it back to disk. - The
-jsonflag prints the finalgo.modin JSON format instead of writingit back to disk in text format. The JSON output corresponds to these Go types:
type Module struct { Path string Version string}type GoMod struct { Module ModPath Go string Require []Require Exclude []Module Replace []Replace Retract []Retract}type ModPath struct { Path string Deprecated string}type Require struct { Path string Version string Indirect bool}type Replace struct { Old Module New Module}type Retract struct { Low string High string Rationale string}type Tool struct { Path string}Note that this only describes thego.mod file itself, not other modulesreferred to indirectly. For the full set of modules available to a build,usego list -m -json all. Seego list -m.
For example, a tool can obtain thego.mod file as a data structure byparsing the output ofgo mod edit -json and can then make changes by invokinggo mod edit with-require,-exclude, and so on.
Tools may also use the packagegolang.org/x/mod/modfileto parse, edit, and formatgo.mod files.
go mod graph
Usage:
go mod graph [-go=version]Thego mod graph command prints themodule requirementgraph (with replacements applied) in text form. Forexample:
example.com/main example.com/a@v1.1.0example.com/main example.com/b@v1.2.0example.com/a@v1.1.0 example.com/b@v1.1.1example.com/a@v1.1.0 example.com/c@v1.3.0example.com/b@v1.1.0 example.com/c@v1.1.0example.com/b@v1.2.0 example.com/c@v1.2.0Each vertex in the module graph represents a specific version of a module.Each edge in the graph represents a requirement on a minimum version of adependency.
go mod graph prints the edges of the graph, one per line. Each line has twospace-separated fields: a module version and one of its dependencies. Eachmodule version is identified as a string of the formpath@version. The mainmodule has no@version suffix, since it has no version.
The-go flag causesgo mod graph to report the module graph asloaded by the given Go version, instead of the version indicated bythego directive in thego.mod file.
SeeMinimal version selection (MVS) for moreinformation on how versions are chosen. See alsogo list -m forprinting selected versions andgo mod why for understandingwhy a module is needed.
go mod init
Usage:
go mod init [module-path]Example:
go mod initgo mod init example.com/mThego mod init command initializes and writes a newgo.mod file in thecurrent directory, in effect creating a new module rooted at the currentdirectory. Thego.mod file must not already exist.
init accepts one optional argument, themodule path forthe new module. SeeModule paths for instructions on choosinga module path. If the module path argument is omitted,init will attemptto infer the module path using import comments in.go files and thecurrent directory (if inGOPATH).
go mod tidy
Usage:
go mod tidy [-e] [-v] [-x] [-diff] [-go=version] [-compat=version]go mod tidy ensures that thego.mod file matches the source code in themodule. It adds any missing module requirements necessary to build the currentmodule’s packages and dependencies, and it removes requirements on modules thatdon’t provide any relevant packages. It also adds any missing entries togo.sum and removes unnecessary entries.
The-e flag (added in Go 1.16) causesgo mod tidy to attempt to proceeddespite errors encountered while loading packages.
The-v flag causesgo mod tidy to print information about removed modulesto standard error.
The-x flag causesgo mod tidy to print the commandstidy executes.
The-diff flag causesgo mod tidy not to modify go.mod or go.sum butinstead print the necessary changes as a unified diff. It exitswith a non-zero code if the diff is not empty.
go mod tidy works by loading all of the packages in themainmodule, all of its tools, and all of the packages they import,recursively. This includes packages imported by tests (including tests in othermodules).go mod tidy acts as if all build tags are enabled, so it willconsider platform-specific source files and files that require custom buildtags, even if those source files wouldn’t normally be built. There is oneexception: theignore build tag is not enabled, so a file with the buildconstraint// +build ignore will not be considered. Note thatgo mod tidywill not consider packages in the main module in directories namedtestdata orwith names that start with. or_ unless those packages are explicitlyimported by other packages.
Oncego mod tidy has loaded this set of packages, it ensures that each modulethat provides one or more packages has arequire directive in the mainmodule’sgo.mod file or — if the main module is atgo 1.16 or below — isrequired by another required module.go mod tidy will add a requirement on thelatest version of each missing module (seeVersion queriesfor the definition of thelatest version).go mod tidy will removerequiredirectives for modules that don’t provide any packages in the set describedabove.
go mod tidy may also add or remove// indirect comments onrequiredirectives. An// indirect comment denotes a module that does not provide apackage imported by a package in the main module. (See therequiredirective for more detail on when// indirectdependencies and comments are added.)
If the-go flag is set,go mod tidy will update thegodirective to the indicated version, enabling or disablingmodule graph pruning andlazy module loading(and adding or removing indirect requirements as needed) according to thatversion.
By default,go mod tidy will check that theselectedversions of modules do not change when the module graphis loaded by the Go version immediately preceding the version indicated in thego directive. The versioned checked for compatibility can also be specifiedexplicitly via the-compat flag.
go mod vendor
Usage:
go mod vendor [-e] [-v] [-o]Thego mod vendor command constructs a directory namedvendor in themainmodule’s root directory that contains copies of all packagesneeded to support builds and tests of packages in the main module. Packagesthat are only imported by tests of packages outside the main module are notincluded. As withgo mod tidy and other module commands,build constraints except forignore are notconsidered when constructing thevendor directory.
When vendoring is enabled, thego command will load packages from thevendordirectory instead of downloading modules from their sources into the modulecache and using packages those downloaded copies. SeeVendoringfor more information.
go mod vendor also creates the filevendor/modules.txt that contains a listof vendored packages and the module versions they were copied from. Whenvendoring is enabled, this manifest is used as a source of module versioninformation, as reported bygo list -m andgo version -m. When thego command readsvendor/modules.txt, it checksthat the module versions are consistent withgo.mod. Ifgo.mod changed sincevendor/modules.txt was generated,go mod vendor should be run again.
Note thatgo mod vendor removes thevendor directory if it exists beforere-constructing it. Local changes should not be made to vendored packages.Thego command does not check that packages in thevendor directory havenot been modified, but one can verify the integrity of thevendor directoryby runninggo mod vendor and checking that no changes were made.
The-e flag (added in Go 1.16) causesgo mod vendor to attempt to proceeddespite errors encountered while loading packages.
The-v flag causesgo mod vendor to print the names of vendored modulesand packages to standard error.
The-o flag (added in Go 1.18) causesgo mod vendor to output the vendortree at the specified directory instead ofvendor. The argument can be eitheran absolute path or a path relative to the module root.
go mod verify
Usage:
go mod verifygo mod verify checks that dependencies of themain modulestored in themodule cache have not been modified sincethey were downloaded. To perform this check,go mod verify hashes eachdownloaded module.zip file and extracted directory, thencompares those hashes with a hash recorded when the module was firstdownloaded.go mod verify checks each module in thebuildlist (which may be printed withgo list -m all).
If all the modules are unmodified,go mod verify prints “all modulesverified”. Otherwise, it reports which modules have been changed and exits witha non-zero status.
Note that all module-aware commands verify that hashes in the main module’sgo.sum file match hashes recorded for modules downloaded into the modulecache. If a hash is missing fromgo.sum (for example, because the module isbeing used for the first time), thego command verifies its hash using thechecksum database (unless the module path is matched byGOPRIVATE orGONOSUMDB). SeeAuthenticating modules fordetails.
In contrast,go mod verify checks that module.zip files and their extracteddirectories have hashes that match hashes recorded in the module cache when theywere first downloaded. This is useful for detecting changes to files in themodule cacheafter a module has been downloaded and verified.go mod verifydoes not download content for modules not in the cache, and it does not usego.sum files to verify module content. However,go mod verify may downloadgo.mod files in order to performminimal versionselection. It will usego.sum to verify thosefiles, and it may addgo.sum entries for missing hashes.
go mod why
Usage:
go mod why [-m] [-vendor] packages...go mod why shows a shortest path in the import graph from the main module toeach of the listed packages.
The output is a sequence of stanzas, one for each package or module named on thecommand line, separated by blank lines. Each stanza begins with a comment linestarting with# giving the target package or module. Subsequent lines give apath through the import graph, one package per line. If the package or moduleis not referenced from the main module, the stanza will display a singleparenthesized note indicating that fact.
For example:
$ go mod why golang.org/x/text/language golang.org/x/text/encoding# golang.org/x/text/languagersc.io/quotersc.io/samplergolang.org/x/text/language# golang.org/x/text/encoding(main module does not need package golang.org/x/text/encoding)The-m flag causesgo mod why to treat its arguments as a list of modules.go mod why will print a path to any package in each of the modules. Note thateven when-m is used,go mod why queries the package graph, not themodule graph printed bygo mod graph.
The-vendor flag causesgo mod why to ignore imports in tests of packagesoutside the main module (asgo mod vendor does). By default,go mod why considers the graph of packages matched by theall pattern. Thisflag has no effect after Go 1.16 in modules that declarego 1.16 or higher(using thego directive ingo.mod), since the meaning ofall changed to match the set of packages matched bygo mod vendor.
go version -m
Usage:
go version [-m] [-v] [file ...]Example:
# Print Go version used to build go.$ go version# Print Go version used to build a specific executable.$ go version ~/go/bin/gopls# Print Go version and module versions used to build a specific executable.$ go version -m ~/go/bin/gopls# Print Go version and module versions used to build executables in a directory.$ go version -m ~/go/bin/go version reports the Go version used to build each executable file namedon the command line.
If no files are named on the command line,go version prints its own versioninformation.
If a directory is named,go version walks that directory, recursively, lookingfor recognized Go binaries and reporting their versions. By default,go version does not report unrecognized files found during a directory scan. The-v flag causes it to report unrecognized files.
The-m flag causesgo version to print each executable’s embedded moduleversion information, when available. For each executable,go version -m printsa table with tab-separated columns like the one below.
$ go version -m ~/go/bin/goimports/home/jrgopher/go/bin/goimports: go1.14.3 path golang.org/x/tools/cmd/goimports mod golang.org/x/tools v0.0.0-20200518203908-8018eb2c26ba h1:0Lcy64USfQQL6GAJma8BdHCgeofcchQj+Z7j0SXYAzU= dep golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= dep golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=The format of the table may change in the future. The same information may beobtained fromruntime/debug.ReadBuildInfo.
The meaning of each row in the table is determined by the word in the firstcolumn.
path: the path of themainpackage used to build the executable.mod: the module containing themainpackage. The columns are themodule path, version, and sum, respectively. Themainmodule has the version(devel)and no sum.dep: a module that provided one or more packages linked into theexecutable. Same format asmod.=>: areplacement for the module on the previousline. If the replacement is a local directory, only the directory path islisted (no version or sum). If the replacement is a module version, the path,version, and sum are listed, as withmodanddep. A replaced module hasno sum.
go clean -modcache
Usage:
go clean [-modcache]The-modcache flag causesgo clean to remove the entiremodule cache, including unpacked source code of versioneddependencies.
This is usually the best way to remove the module cache. By default, most filesand directories in the module cache are read-only to prevent tests and editorsfrom unintentionally changing files after they’ve beenauthenticated. Unfortunately, this causes commands likerm -r to fail, since files can’t be removed without first making their parentdirectories writable.
The-modcacherw flag (accepted bygo build andother module-aware commands) causes new directories in the module cache tobe writable. To pass-modcacherw to all module-aware commands, add it to theGOFLAGS variable.GOFLAGS may be set in the environment or withgo env -w. Forexample, the command below sets it permanently:
go env -w GOFLAGS=-modcacherw-modcacherw should be used with caution; developers should be careful notto make changes to files in the module cache.go mod verifymay be used to check that files in the cache match hashes in the main module’sgo.sum file.
Version queries
Several commands allow you to specify a version of a module using aversionquery, which appears after an@ character following a module or package pathon the command line.
Examples:
go get example.com/m@latestgo mod download example.com/m@mastergo list -m -json example.com/m@e3702bed2A version query may be one of the following:
- A fully-specified semantic version, such as
v1.2.3, which selects aspecific version. SeeVersions for syntax. - A semantic version prefix, such as
v1orv1.2, which selects the highestavailable version with that prefix. - A semantic version comparison, such as
<v1.2.3or>=v1.5.6, which selectsthe nearest available version to the comparison target (the lowest versionfor>and>=, and the highest version for<and<=). - A revision identifier for the underlying source repository, such as a commithash prefix, revision tag, or branch name. If the revision is tagged with asemantic version, this query selects that version. Otherwise, this queryselects apseudo-version for the underlyingcommit. Note that branches and tags with names matched by other versionqueries cannot be selected this way. For example, the query
v2selects thelatest version starting withv2, not the branch namedv2. - The string
latest, which selects the highest available release version. Ifthere are no release versions,latestselects the highest pre-releaseversion. If there are no tagged versions,latestselects a pseudo-version forthe commit at the tip of the repository’s default branch. - The string
upgrade, which is likelatestexcept that if the module iscurrently required at a higher version than the versionlatestwould select(for example, a pre-release),upgradewill select the current version. - The string
patch, which selects the latest available version with the samemajor and minor version numbers as the currently required version. If noversion is currently required,patchis equivalent tolatest. SinceGo 1.16,go getrequires a current version when usingpatch(but the-u=patchflag does not have this requirement).
Except for queries for specific named versions or revisions, all queriesconsider available versions reported bygo list -m -versions (seego list -m). This list contains only tagged versions, not pseudo-versions.Module versions disallowed byexclude directives inthe main module’sgo.mod file are not considered.Versions covered byretract directives in thego.modfile from thelatest version of the same module are also ignored except whenthe-retracted flag is used withgo list -m and except whenloadingretract directives.
Release versions are preferred over pre-releaseversions. For example, if versionsv1.2.2 andv1.2.3-pre are available, thelatest query will selectv1.2.2, even thoughv1.2.3-pre is higher. The<v1.2.4 query would also selectv1.2.2, even thoughv1.2.3-pre is closertov1.2.4. If no release or pre-release version is available, thelatest,upgrade, andpatch queries will select a pseudo-version for the commitat the tip of the repository’s default branch. Other queries will reportan error.
Module commands outside a module
Module-aware Go commands normally run in the context of amainmodule defined by ago.mod file in the working directoryor a parent directory. Some commands may be run in module-aware mode without ago.mod file, but most commands work differently or report an error when nogo.mod file is present.
SeeModule-aware commands for information on enabling anddisabling module-aware mode.
| Command | Behavior |
|---|---|
go buildgo docgo fixgo fmtgo generatego installgo listgo rungo testgo vet | Only packages in the standard library and packages specified as.go files on the command line can be loaded, imported, and built. Packages from other modules cannot be built, since there is no place to record module requirements and ensure deterministic builds. |
go get | Packages and executables may be built and installed as usual. Note that there is no main module whengo get is run without ago.mod file, soreplace andexclude directives are not applied. |
go list -m | Explicitversion queries are required for most arguments, except when the-versions flag is used. |
go mod download | Explicitversion queries are required for most arguments. |
go mod edit | An explicit file argument is required. |
go mod graphgo mod tidygo mod vendorgo mod verifygo mod why | These commands require ago.mod file and will report an error if one is not present. |
go work init
Usage:
go work init [moddirs]Init initializes and writes a new go.work file in thecurrent directory, in effect creating a new workspace at the currentdirectory.
go work init optionally accepts paths to the workspace modules asarguments. If the argument is omitted, an empty workspace with nomodules will be created.
Each argument path is added to a use directive in the go.work file. Thecurrent go version will also be listed in the go.work file.
go work edit
Usage:
go work edit [editing flags] [go.work]Thego work edit command provides a command-line interface for editinggo.work,for use primarily by tools or scripts. It only readsgo.work;it does not look up information about the modules involved.If no file is specified, Edit looks for ago.work file in the currentdirectory and its parent directories
The editing flags specify a sequence of editing operations.
- The
-fmtflag reformats the go.work file without making other changes.This reformatting is also implied by any other modifications that use orrewrite thego.workfile. The only time this flag is needed is if no otherflags are specified, as in ‘go work edit-fmt’. - The
-use=pathand-dropuse=pathflagsadd and drop a use directive from thego.workfile’s set of module directories. - The
-replace=old[@v]=new[@v]flag adds a replacement of the givenmodule path and version pair. If the@vinold@vis omitted, areplacement without a version on the left side is added, which appliesto all versions of the old module path. If the@vinnew@vis omitted,the new path should be a local module root directory, not a modulepath. Note that-replaceoverrides any redundant replacements forold[@v],so omitting@vwill drop existing replacements for specific versions. - The
-dropreplace=old[@v]flag drops a replacement of the givenmodule path and version pair. If the@vis omitted, a replacement withouta version on the left side is dropped. - The
-go=versionflag sets the expected Go language version.
The editing flags may be repeated. The changes are applied in the order given.
go work edit has additional flags that control its output
- The -print flag prints the final go.work in its text format instead ofwriting it back to go.mod.
- The -json flag prints the final go.work file in JSON format instead ofwriting it back to go.mod. The JSON output corresponds to these Go types:
type Module struct { Path string Version string}type GoWork struct { Go string Directory []Directory Replace []Replace}type Use struct { Path string ModulePath string}type Replace struct { Old Module New Module}go work use
Usage:
go work use [-r] [moddirs]Thego work use command provides a command-line interface for addingdirectories, optionally recursively, to ago.work file.
Ause directive will be added to thego.work file for each argumentdirectory listed on the command linego.work file, if it exists on disk,or removed from thego.work file if it does not exist on disk.
The-r flag searches recursively for modules in the argumentdirectories, and the use command operates as if each of the directorieswere specified as arguments.
go work sync
Usage:
go work syncThego work sync command syncs the workspace’s build list back to theworkspace’s modules.
The workspace’s build list is the set of versions of all the(transitive) dependency modules used to do builds in the workspace.go work sync generates that build list using theMinimal Version Selection(MVS)algorithm, and then syncs those versions back to each of modulesspecified in the workspace (withuse directives).
Once the workspace build list is computed, thego.mod file for eachmodule in the workspace is rewritten with the dependencies relevantto that module upgraded to match the workspace build list.Note thatMinimal Version Selectionguarantees that the build list’s version of each module is alwaysthe same or higher than that in each workspace module.
Module proxies
GOPROXY protocol
Amodule proxy is an HTTP server that can respond toGET requestsfor paths specified below. The requests have no query parameters, and nospecific headers are required, so even a site serving from a fixed file system(including afile:// URL) can be a module proxy.
Successful HTTP responses must have the status code 200 (OK). Redirects (3xx)are followed. Responses with status codes 4xx and 5xx are treated as errors.The error codes 404 (Not Found) and 410 (Gone) indicate that therequested module or version is not available on the proxy, but it may be foundelsewhere. Error responses should have content typetext/plain withcharset eitherutf-8 orus-ascii.
Thego command may be configured to contact proxies or source control serversusing theGOPROXY environment variable, which accepts a list of proxy URLs.The list may include the keywordsdirect oroff (seeEnvironmentvariables for details). List elements may be separatedby commas (,) or pipes (|), which determine error fallback behavior. When aURL is followed by a comma, thego command falls back to later sources onlyafter a 404 (Not Found) or 410 (Gone) response. When a URL is followed by apipe, thego command falls back to later sources after any error, includingnon-HTTP errors such as timeouts. This error handling behavior lets a proxy actas a gatekeeper for unknown modules. For example, a proxy could respond witherror 403 (Forbidden) for modules not on an approved list (seePrivate proxyserving private modules).
The table below specifies queries that a module proxy must respond to. For eachpath,$base is the path portion of a proxy URL,$module is a module path, and$version is a version. For example, if the proxy URL ishttps://example.com/mod, and the client is requesting thego.mod file forthe modulegolang.org/x/text at versionv0.3.2, the client would send aGET request forhttps://example.com/mod/golang.org/x/text/@v/v0.3.2.mod.
To avoid ambiguity when serving from case-insensitive file systems,the$module and$version elements are case-encoded by replacing everyuppercase letter with an exclamation mark followed by the correspondinglower-case letter. This allows modulesexample.com/M andexample.com/m toboth be stored on disk, since the former is encoded asexample.com/!m.
| Path | Description |
|---|---|
$base/$module/@v/list | Returns a list of known versions of the given module in plain text, one per line. This list should not include pseudo-versions. |
$base/$module/@v/$version.info | Returns JSON-formatted metadata about a specific version of a module. The response must be a JSON object that corresponds to the Go data structure below: type Info struct { Version string // version string Time time.Time // commit time} The The More fields may be added in the future, so other names are reserved. |
$base/$module/@v/$version.mod | Returns thego.mod file for a specific version of a module. If the module does not have ago.mod file at the requested version, a file containing only amodule statement with the requested module path must be returned. Otherwise, the original, unmodifiedgo.mod file must be returned. |
$base/$module/@v/$version.zip | Returns a zip file containing the contents of a specific version of a module. SeeModule zip files for details on how this zip file must be formatted. |
$base/$module/@latest | Returns JSON-formatted metadata about the latest known version of a module in the same format as$base/$module/@v/$version.info. The latest version should be the version of the module that thego command should use if$base/$module/@v/list is empty or no listed version is suitable. This endpoint is optional, and module proxies are not required to implement it. |
When resolving the latest version of a module, thego command will request$base/$module/@v/list, then, if no suitable versions are found,$base/$module/@latest. Thego command prefers, in order: the semanticallyhighest release version, the semantically highest pre-release version, and thechronologically most recent pseudo-version. In Go 1.12 and earlier, thegocommand considered pseudo-versions in$base/$module/@v/list to be pre-releaseversions, but this is no longer true since Go 1.13.
A module proxy must always serve the same content for successfulresponses for$base/$module/$version.mod and$base/$module/$version.zipqueries. This content iscryptographically authenticatedusinggo.sum files and, by default, thechecksum database.
Thego command caches most content it downloads from module proxies in itsmodule cache in$GOPATH/pkg/mod/cache/download. Even when downloading directlyfrom version control systems, thego command synthesizes explicitinfo,mod, andzip files and stores them in this directory, the same as if it haddownloaded them directly from a proxy. The cache layout is the same as the proxyURL space, so serving$GOPATH/pkg/mod/cache/download at (or copying it to)https://example.com/proxy would let users access cached module versions bysettingGOPROXY tohttps://example.com/proxy.
Communicating with proxies
Thego command may download module source code and metadata from amoduleproxy. TheGOPROXYenvironmentvariable may be used to configure which proxies thego command may connect to and whether it may communicate directly withversion control systems. Downloaded module data is saved in themodulecache. Thego command will only contact a proxy when itneeds information not already in the cache.
TheGOPROXY protocol section describes requests thatmay be sent to aGOPROXY server. However, it’s also helpful to understandwhen thego command makes these requests. For example,go build followsthe procedure below:
- Compute thebuild list by reading
go.modfiles and performingminimal version selection(MVS). - Read the packages named on the command line and the packages they import.
- If a package is not provided by any module in the build list, find a modulethat provides it. Add a module requirement on its latest version to
go.mod,and start over. - Build packages after everything is loaded.
When thego command computes the build list, it loads thego.mod file foreach module in themodule graph. If ago.mod file is notin the cache, thego command will download it from the proxy using a$module/@v/$version.mod request (where$module is the module path and$version is the version). These requests can be tested with a tool likecurl. For example, the command below downloads thego.mod file forgolang.org/x/mod at versionv0.2.0:
$ curl https://proxy.golang.org/golang.org/x/mod/@v/v0.2.0.modmodule golang.org/x/modgo 1.12require ( golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898)In order to load a package, thego command needs the source code for themodule that provides it. Module source code is distributed in.zip files whichare extracted into the module cache. If a module.zip is not in the cache,thego command will download it using a$module/@v/$version.zip request.
$ curl -O https://proxy.golang.org/golang.org/x/mod/@v/v0.2.0.zip$ unzip -l v0.2.0.zip | headArchive: v0.2.0.zip Length Date Time Name--------- ---------- ----- ---- 1479 00-00-1980 00:00 golang.org/x/mod@v0.2.0/LICENSE 1303 00-00-1980 00:00 golang.org/x/mod@v0.2.0/PATENTS 559 00-00-1980 00:00 golang.org/x/mod@v0.2.0/README 21 00-00-1980 00:00 golang.org/x/mod@v0.2.0/codereview.cfg 214 00-00-1980 00:00 golang.org/x/mod@v0.2.0/go.mod 1476 00-00-1980 00:00 golang.org/x/mod@v0.2.0/go.sum 5224 00-00-1980 00:00 golang.org/x/mod@v0.2.0/gosumcheck/main.goNote that.mod and.zip requests are separate, even thoughgo.mod filesare usually contained within.zip files. Thego command may need to downloadgo.mod files for many different modules, and.mod files are much smallerthan.zip files. Additionally, if a Go project does not have ago.mod file,the proxy will serve a syntheticgo.mod file that only contains amoduledirective. Syntheticgo.mod files are generated by thego command when downloading from aversion control system.
If thego command needs to load a package not provided by any module in thebuild list, it will attempt to find a new module that provides it. The sectionResolving a package to a module describes this process. Insummary, thego command requests information about the latest version of eachmodule path that could possibly contain the package. For example, for thepackagegolang.org/x/net/html, thego command would try to find the latestversions of the modulesgolang.org/x/net/html,golang.org/x/net,golang.org/x/, andgolang.org. Onlygolang.org/x/net actually exists andprovides that package, so thego command uses the latest version of thatmodule. If more than one module provides the package, thego command will usethe module with the longest path.
When thego command requests the latest version of a module, it first sends arequest for$module/@v/list. If the list is empty or none of the returnedversions can be used, it sends a request for$module/@latest. Once a versionis chosen, thego command sends a$module/@v/$version.info request formetadata. It may then send$module/@v/$version.mod and$module/@v/$version.zip requests to load thego.mod file and source code.
$ curl https://proxy.golang.org/golang.org/x/mod/@v/listv0.1.0v0.2.0$ curl https://proxy.golang.org/golang.org/x/mod/@v/v0.2.0.info{"Version":"v0.2.0","Time":"2020-01-02T17:33:45Z"}After downloading a.mod or.zip file, thego command computes acryptographic hash and checks that it matches a hash in the main module’sgo.sum file. If the hash is not present ingo.sum, by default, thegocommand retrieves it from thechecksum database. If thecomputed hash does not match, thego command reports a security error and doesnot install the file in the module cache. TheGOPRIVATE andGONOSUMDBenvironment variables may be used to disable requeststo the checksum database for specific modules. TheGOSUMDB environmentvariable may also be set tooff to disable requests to the checksum databaseentirely. SeeAuthenticating modules for moreinformation. Note that version lists and version metadata returned for.inforequests are not authenticated and may change over time.
Serving modules directly from a proxy
Most modules are developed and served from a version control repository. Indirect mode, thego command downloads such a module witha version control tool (seeVersion control systems). It’s also possibleto serve a module directly from a module proxy. This is useful for organizationsthat want to serve modules without exposing their version control servers andfor organizations that use version control tools thego command does notsupport.
When thego command downloads a module in direct mode, it first looks up themodule server’s URL with an HTTP GET request based on the module path. It looksfor a<meta> tag with the namego-import in the HTML response. The tag’scontent must contain therepository rootpath, the version control system, and the URL,separated by spaces. SeeFinding a repository for a module path fordetails.
If the version control system ismod, thego command downloads the modulefrom the given URL using theGOPROXY protocol.
For example, suppose thego command is attempting to download the moduleexample.com/gopher at versionv1.0.0. It sends a request tohttps://example.com/gopher?go-get=1. The server responds with an HTML documentcontaining the tag:
<meta name="go-import" content="example.com/gopher mod https://modproxy.example.com">Based on this response, thego command downloads the module by sendingrequests forhttps://modproxy.example.com/example.com/gopher/@v/v1.0.0.info,v1.0.0.mod, andv1.0.0.zip.
Note that modules served directly from a proxy cannot be downloaded withgo get in GOPATH mode.
Version control systems
Thego command may download module source code and metadata directly from aversion control repository. Downloading a module from aproxy is usually faster, but connecting directlyto a repository is necessary if a proxy is not available or if a module’srepository is not accessible to a proxy (frequently true for privaterepositories). Git, Subversion, Mercurial, Bazaar, and Fossil are supported. Aversion control tool must be installed in a directory inPATH in order for thego command to use it.
To download specific modules from source repositories instead of a proxy, settheGOPRIVATE orGONOPROXY environment variables. To configure thegocommand to download all modules directly from source repositories, setGOPROXYtodirect. SeeEnvironment variables for moreinformation.
Finding a repository for a module path
When thego command downloads a module indirect mode, it starts by locatingthe repository that contains the module.
If the module path has a VCS qualifier (one of.bzr,.fossil,.git,.hg,.svn) at the end of a path component, thego command will use everything upto that path qualifier as the repository URL. For example, for the moduleexample.com/foo.git/bar, thego command downloads the repository atexample.com/foo using git, expecting to find the module in thebarsubdirectory. Thego command will guess the protocol to use based on theprotocols supported by the version control tool.
If the module path does not have a qualifier, thego command sends an HTTPGET request to a URL derived from the module path with a?go-get=1 querystring. For example, for the modulegolang.org/x/mod, thego command maysend the following requests:
https://golang.org/x/mod?go-get=1 (preferred)http://golang.org/x/mod?go-get=1 (fallback, only with GOINSECURE)Thego command follows redirects but otherwise ignores response statuscodes, so the server may respond with a 404 or any other error status. TheGOINSECURE environment variable may be set to allow fallback and redirects tounencrypted HTTP for specific modules.
The server must respond with an HTML document containing a<meta> tag in thedocument’s<head>. The<meta> tag should appear early in the document toavoid confusing thego command’s restricted parser. In particular, it shouldappear before any raw JavaScript or CSS. The<meta> tag must have the form:
<meta name="go-import" content="root-path vcs repo-url [subdirectory]">root-path is the repository root path, the portion of the module path thatcorresponds to the repository’s root directory, or to thesubdirectory,if present and using Go 1.25 or later (see the section onsubdirectory below).It must be a prefix or an exact match of the requested module path. If it’snot an exact match, another request is made for the prefix to verify the<meta>tags match.
vcs is the version control system. It must be one of the tools listed in thetable below or the keywordmod, which instructs thego command to downloadthe module from the given URL using theGOPROXYprotocol. SeeServing modules directly from aproxy for details.
repo-url is the repository’s URL. If the URL does not include a scheme (eitherbecause the module path has a VCS qualifier or because the<meta> tag lacks ascheme), thego command will try each protocol supported by the versioncontrol system. For example, with Git, thego command will tryhttps:// thengit+ssh://. Insecure protocols (likehttp:// andgit://) may only be usedif the module path is matched by theGOINSECURE environment variable.
subdirectory, if present, is the slash-separated subdirectory of the repositorythat theroot-path corresponds to, overriding the default of the repository’sroot directory.go-import meta tags providing asubdirectory are only recognizedby Go 1.25 and later. Attempts to fetch resolve modules on earlier versions ofGo will ignore the meta tag and result in a resolution failure if the module cannot be resolved elsewhere.
| Name | Command | GOVCS default | Secure schemes |
|---|---|---|---|
| Bazaar | bzr | Private only | https,bzr+ssh |
| Fossil | fossil | Private only | https |
| Git | git | Public and private | https,git+ssh,ssh |
| Mercurial | hg | Public and private | https,ssh |
| Subversion | svn | Private only | https,svn+ssh |
As an example, considergolang.org/x/mod again. Thego command sendsa request tohttps://golang.org/x/mod?go-get=1. The server respondswith an HTML document containing the tag:
<meta name="go-import" content="golang.org/x/mod git https://go.googlesource.com/mod">From this response, thego command will use the Git repository atthe remote URLhttps://go.googlesource.com/mod.
GitHub and other popular hosting services respond to?go-get=1 queries forall repositories, so usually no server configuration is necessary for moduleshosted at those sites.
After the repository URL is found, thego command will clone the repositoryinto the module cache. In general, thego command tries to avoid fetchingunneeded data from a repository. However, the actual commands used vary byversion control system and may change over time. For Git, thego command canlist most available versions without downloading commits. It will usually fetchcommits without downloading ancestor commits, but doing so is sometimesnecessary.
Mapping versions to commits
Thego command may check out a module within a repository at a specificcanonical version likev1.2.3,v2.4.0-beta, orv3.0.0+incompatible. Each module version should have asemantic versiontag within the repository that indicates which revision should be checkedout for a given version.
If a module is defined in the repository root directory or in a major versionsubdirectory of the root directory, then each version tag name is equal to thecorresponding version. For example, the modulegolang.org/x/text is defined inthe root directory of its repository, so the versionv0.3.2 has the tagv0.3.2 in that repository. This is true for most modules.
If a module is defined in a subdirectory within the repository, that is, themodule subdirectory portion of the module path isnot empty, then each tag name must be prefixed with the module subdirectory,followed by a slash. For example, the modulegolang.org/x/tools/gopls isdefined in thegopls subdirectory of the repository with root pathgolang.org/x/tools. The versionv0.4.0 of that module must have the tagnamedgopls/v0.4.0 in that repository.
The major version number of a semantic version tag must be consistent with themodule path’s major version suffix (if any). For example, the tagv1.0.0 couldbelong to the moduleexample.com/mod but notexample.com/mod/v2, which wouldhave tags likev2.0.0.
A tag with major versionv2 or higher may belong to a module without a majorversion suffix if nogo.mod file is present, and the module is in therepository root directory. This kind of version is denoted with the suffix+incompatible. The version tag itself must not have the suffix. SeeCompatibility with non-module repositories.
Once a tag is created, it should not be deleted or changed to a differentrevision. Versions areauthenticated to ensure safe,repeatable builds. If a tag is modified, clients may see a security error whendownloading it. Even after a tag is deleted, its content may remainavailable onmodule proxies.
Mapping pseudo-versions to commits
Thego command may check out a module within a repository at a specificrevision, encoded as apseudo-version likev1.3.2-0.20191109021931-daa7c04131f5.
The last 12 characters of the pseudo-version (daa7c04131f5 in the exampleabove) indicate a revision in the repository to check out. The meaning of thisdepends on the version control system. For Git and Mercurial, this is a prefixof a commit hash. For Subversion, this is a zero-padded revision number.
Before checking out a commit, thego command verifies that the timestamp(20191109021931 above) matches the commit date. It also verifies that the baseversion (v1.3.1, the version beforev1.3.2 in the example above) correspondsto a semantic version tag that is an ancestor of the commit. These checks ensurethat module authors have full control over how pseudo-versions compare withother released versions.
SeePseudo-versions for more information.
Mapping branches and commits to versions
A module may be checked out at a specific branch, tag, or revision using aversion query.
go get example.com/mod@masterThego command converts these names intocanonicalversions that can be used withminimal versionselection (MVS). MVS depends on the ability toorder versions unambiguously. Branch names and revisions can’t be comparedreliably over time, since they depend on repository structure which may change.
If a revision is tagged with one or more semantic version tags likev1.2.3,the tag for the highest valid version will be used. Thego command onlyconsiders semantic version tags that could belong to the target module; forexample, the tagv1.5.2 would not be considered forexample.com/mod/v2 sincethe major version doesn’t match the module path’s suffix.
If a revision is not tagged with a valid semantic version tag, thego commandwill generate apseudo-version. If the revision hasancestors with valid semantic version tags, the highest ancestor version will beused as the pseudo-version base. SeePseudo-versions.
Module directories within a repository
Once a module’s repository has been checked out at a specific revision, thegocommand must locate the directory that contains the module’sgo.mod file(the module’s root directory).
Recall that amodule path consists of three parts: arepository root path (corresponding to the repository root directory),a module subdirectory, and a major version suffix (only for modules released atv2 or higher).
For most modules, the module path is equal to the repository root path, sothe module’s root directory is the repository’s root directory.
Modules are sometimes defined in repository subdirectories. This is typicallydone for large repositories with multiple components that need to be releasedand versioned independently. Such a module is expected to be found in asubdirectory that matches the part of the module’s path after the repositoryroot path. For example, suppose the moduleexample.com/monorepo/foo/bar is inthe repository with root pathexample.com/monorepo. Itsgo.mod file must bein thefoo/bar subdirectory.
If a module is released at major versionv2 or higher, its path must have amajor version suffix. A module with a major versionsuffix may be defined in one of two subdirectories: one with the suffix,and one without. For example, suppose a new version of the module above isreleased with the pathexample.com/monorepo/foo/bar/v2. Itsgo.mod filemay be in eitherfoo/bar orfoo/bar/v2.
Subdirectories with a major version suffix aremajor versionsubdirectories. They may be used to develop multiple major versions of amodule on a single branch. This may be unnecessary when development of multiplemajor versions proceeds on separate branches. However, major versionsubdirectories have an important property: inGOPATH mode, package importpaths exactly match directories underGOPATH/src. Thego command providesminimal module compatibility inGOPATH mode (seeCompatibility withnon-module repositories), so major versionsubdirectories aren’t always necessary for compatibility with projects built inGOPATH mode. Older tools that don’t support minimal module compatibilitymay have problems though.
Once thego command has found the module root directory, it creates a.zipfile of the contents of the directory, then extracts the.zip file into themodule cache. SeeFile path and size constraintsfor details on what files may be included in the.zip file. The contents ofthe.zip file areauthenticated before extraction into themodule cache the same way they would be if the.zip file were downloaded froma proxy.
Module zip files do not include the contents ofvendor directories or anynested modules (subdirectories that containgo.mod files). This means a modulemust take care not to refer to files outside its directory or in other modules.For example,//go:embed patternsmust not match files in nested modules. This behavior may serve as a usefulworkaround in situations where files should not be included in a module.For example, if a repository has large files checked into atestdatadirectory, the module author could add an emptygo.mod file intestdataso their users don’t need to download those files. Of course, this may reducecoverage for users testing their dependencies.
Special case for LICENSE files
When thego command creates a.zip file for a module that is not in therepository root directory, if the module does not have a file namedLICENSEin its root directory (alongsidego.mod), thego command will copy thefile namedLICENSE from the repository root directory if it is present inthe same revision.
This special case allows the sameLICENSE file to apply to all modules withina repository. This only applies to files namedLICENSE specifically, withoutextensions like.txt. Unfortunately, this cannot be extended without breakingcryptographic sums of existing modules; seeAuthenticatingmodules. Other tools and websites likepkg.go.dev may recognize files with other names.
Note also that thego command does not include symbolic links when creatingmodule.zip files; seeFile path and sizeconstraints. Consequently, if a repository does nothave aLICENSE file in its root directory, authors may instead create copiesof their license files in modules defined in subdirectories to ensure thosefiles are included in module.zip files.
Controlling version control tools withGOVCS
Thego command’s ability to download modules with version control commandslikegit is critical to the decentralized package ecosystem, in whichcode can be imported from any server. It is also a potential security problemif a malicious server finds a way to cause the invoked version control commandto run unintended code.
To balance the functionality and security concerns, thego command by defaultwill only usegit andhg to download code from public servers. It will useanyknown version control system to download code from privateservers, defined as those hosting packages matching theGOPRIVATEenvironmentvariable. The rationale behind allowing only Git andMercurial is that these two systems have had the most attention to issues ofbeing run as clients of untrusted servers. In contrast, Bazaar, Fossil, andSubversion have primarily been used in trusted, authenticated environments andare not as well scrutinized as attack surfaces.
The version control command restrictions only apply when using direct versioncontrol access to download code. When downloading modules from a proxy, thegocommand uses theGOPROXY protocol instead, which isalways permitted. By default, thego command uses the Go module mirror(proxy.golang.org) for public modules and onlyfalls back to version control for private modules or when the mirror refuses toserve a public package (typically for legal reasons). Therefore, clients canstill access public code served from Bazaar, Fossil, or Subversion repositoriesby default, because those downloads use the Go module mirror, which takes on thesecurity risk of running the version control commands using a custom sandbox.
TheGOVCS variable can be used to change the allowed version control systemsfor specific modules. TheGOVCS variable applies when building packagesin both module-aware mode and GOPATH mode. When using modules, the patterns matchagainst the module path. When using GOPATH, the patterns match against theimport path corresponding to the root of the version control repository.
The general form of theGOVCS variable is a comma-separated list ofpattern:vcslist rules. The pattern is aglob pattern thatmust match one or more leading elements of the module or import path. Thevcslist is a pipe-separated list of allowed version control commands, orallto allow use of any known command, oroff to allow nothing. Note that if amodule matches a pattern with vcslistoff, it may still be downloaded if theorigin server uses themod scheme, which instructs the go command to downloadthe module using theGOPROXY protocol. The earliestmatching pattern in the list applies, even if later patterns might also match.
For example, consider:
GOVCS=github.com:git,evil.com:off,*:git|hgWith this setting, code with a module or import path beginning withgithub.com/ can only usegit; paths onevil.com cannot use any versioncontrol command, and all other paths (* matches everything) can useonlygit orhg.
The special patternspublic andprivate match public and privatemodule or import paths. A path is private if it matches theGOPRIVATEvariable; otherwise it is public.
If no rules in theGOVCS variable match a particular module or import path,thego command applies its default rule, which can now be summarizedinGOVCS notation aspublic:git|hg,private:all.
To allow unfettered use of any version control system for any package, use:
GOVCS=*:allTo disable all use of version control, use:
GOVCS=*:offThego env -wcommand can beused to set theGOVCS variable for future go command invocations.
GOVCS was introduced in Go 1.16. Earlier versions of Go may use any knownversion control tool for any module.
Module zip files
Module versions are distributed as.zip files. There is rarely any need tointeract directly with these files, since thego command creates, downloads,and extracts them automatically frommodule proxies andversion control repositories. However, it’s still useful to know about thesefiles to understand cross-platform compatibility constraints or whenimplementing a module proxy.
Thego mod download command downloads zip filesfor one or more modules, then extracts those files into themodulecache. Depending onGOPROXY and otherenvironmentvariables, thego command may either downloadzip files from a proxy or clone source control repositories and createzip files from them. The-json flag may be used to find the location ofdownload zip files and their extracted contents in the module cache.
Thegolang.org/x/mod/zippackage may be used to create, extract, or check contents of zip filesprogrammatically.
File path and size constraints
There are a number of restrictions on the content of module zip files. Theseconstraints ensure that zip files can be extracted safely and consistently ona wide range of platforms.
- A module zip file may be at most 500 MiB in size. The total uncompressed sizeof its files is also limited to 500 MiB.
go.modfiles are limited to 16 MiB.LICENSEfiles are also limited to 16 MiB. These limits exist to mitigatedenial of service attacks on users, proxies, and other parts of the moduleecosystem. Repositories that contain more than 500 MiB of files in a moduledirectory tree should tag module versions at commits that only include filesneeded to build the module’s packages; videos, models, and other large assetsare usually not needed for builds. - Each file within a module zip file must begin with the prefix
$module@$version/where$moduleis the module path and$versionis theversion, for example,golang.org/x/mod@v0.3.0/. The module path must bevalid, the version must be valid and canonical, and the version must match themodule path’s major version suffix. SeeModule paths andversions for specific definitions and restrictions. - File modes, timestamps, and other metadata are ignored.
- Empty directories (entries with paths ending with a slash) may be includedin module zip files but are not extracted. The
gocommand does not includeempty directories in zip files it creates. - Symbolic links and other irregular files are ignored when creating zip files,since they aren’t portable across operating systems and file systems, andthere’s no portable way to represent them in the zip file format.
- Files within directories named
vendorare ignored when creating zip files,sincevendordirectories outside the main module are never used. - Files within directories containing
go.modfiles, other than the moduleroot directory, are ignored when creating zip files, since they are not partof the module. Thegocommand ignores subdirectories containinggo.modfiles when extracting zip files. - No two files within a zip file may have paths equal under Unicode case-folding(see
strings.EqualFold).This ensures that zip files can be extracted on case-insensitive file systemswithout collisions. - A
go.modfile may or may not appear in the top-level directory($module@$version/go.mod). If present, it must have the namego.mod(alllowercase). Files namedgo.modare not allowed in any other directory. - File and directory names within a module may consist of Unicode letters, ASCIIdigits, the ASCII space character (U+0020), and the ASCII punctuationcharacters
!#$%&()+,-.=@[]^_{}~. Note that package paths may not contain allthese characters. Seemodule.CheckFilePathandmodule.CheckImportPathfor the differences. - A file or directory name up to the first dot must not be a reserved file nameon Windows, regardless of case (
CON,com1,NuL, and so on).
Private modules
Go modules are frequently developed and distributed on version control serversand module proxies that aren’t available on the public internet. Thegocommand can download and build modules from private sources, though it usuallyrequires some configuration.
The environment variables below may be used to configure access to privatemodules. SeeEnvironment variables for details. SeealsoPrivacy for information on controllinginformation sent to public servers.
GOPROXY— list of module proxy URLs. Thegocommand will attempt todownload modules from each server in sequence. The keyworddirectinstructsthegocommand to download modules from version control repositorieswhere they’re developed instead of using a proxy.GOPRIVATE— list of glob patterns of module path prefixes that should beconsidered private. Acts as a default value forGONOPROXYandGONOSUMDB.GONOPROXY— list of glob patterns of module path prefixes that should not bedownloaded from a proxy. Thegocommand will download matching modules fromversion control repositories where they’re developed, regardless ofGOPROXY.GONOSUMDB— list of glob patterns of module path prefixes that should not bechecked using the public checksum database,sum.golang.org.GOINSECURE— list of glob patterns of module path prefixes that may beretrieved over HTTP and other insecure protocols.
These variables may be set in the development environment (for example, in a.profile file), or they may be set permanently withgo env -w.
The rest of this section describes common patterns for providing access toprivate module proxies and version control repositories.
Private proxy serving all modules
A central private proxy server that serves all modules (public and private)provides the most control for administrators and requires the leastconfiguration for individual developers.
To configure thego command to use such a server, set the followingenvironment variables, replacinghttps://proxy.corp.example.com with yourproxy URL andcorp.example.com with your module prefix:
GOPROXY=https://proxy.corp.example.comGONOSUMDB=corp.example.comTheGOPROXY setting instructs thego command to only download modules fromhttps://proxy.corp.example.com; thego command will not connect to otherproxies or version control repositories.
TheGONOSUMDB setting instructs thego command not to use the publicchecksum database to authenticate modules with paths starting withcorp.example.com.
A proxy running in this configuration will likely need read access toprivate version control servers. It will also need access to the public internetto download new versions of public modules.
There are several existing implementations ofGOPROXY servers that may be usedthis way. A minimal implementation would serve files from amodulecache directory and would usego mod download (with suitable configuration) to retrieve missingmodules.
Private proxy serving private modules
A private proxy server may serve private modules without also serving publiclyavailable modules. Thego command can be configured to fall back topublic sources for modules that aren’t available on the private server.
To configure thego command to work this way, set the following environmentvariables, replacinghttps://proxy.corp.example.com with the proxy URL andcorp.example.com with the module prefix:
GOPROXY=https://proxy.corp.example.com,https://proxy.golang.org,directGONOSUMDB=corp.example.comTheGOPROXY setting instructs thego command to try to download modules fromhttps://proxy.corp.example.com first. If that server responds with 404 (NotFound) or 410 (Gone), thego command will fall back tohttps://proxy.golang.org, then to direct connections to repositories.
TheGONOSUMDB setting instructs thego command not to use the publicchecksum database to authenticate modules whose paths start withcorp.example.com.
Note that a proxy used in this configuration may still control access to publicmodules, even though it doesn’t serve them. If the proxy responds to a requestwith an error status other than 404 or 410, thego command will not fall backto later entries in theGOPROXY list. For example, the proxy could respondwith 403 (Forbidden) for a module with an unsuitable license or with knownsecurity vulnerabilities.
Direct access to private modules
Thego command may be configured to bypass public proxies and download privatemodules directly from version control servers. This is useful when running aprivate proxy server is not feasible.
To configure thego command to work this way, setGOPRIVATE, replacingcorp.example.com the private module prefix:
GOPRIVATE=corp.example.comTheGOPROXY variable does not need to be changed in this situation. Itdefaults tohttps://proxy.golang.org,direct, which instructs thego commandto attempt to download modules fromhttps://proxy.golang.org first, then fallback to a direct connection if that proxy responds with 404 (Not Found) or 410(Gone).
TheGOPRIVATE setting instructs thego command not to connect to a proxy orto the checksum database for modules starting withcorp.example.com.
An internal HTTP server may still be needed toresolve module paths torepository URLs. For example, when thego command downloads themodulecorp.example.com/mod, it will send a GET request tohttps://corp.example.com/mod?go-get=1, and it will look for the repository URLin the response. To avoid this requirement, ensure that each private module pathhas a VCS suffix (like.git) marking the repository root prefix. For example,when thego command downloads the modulecorp.example.com/repo.git/mod, itwill clone the Git repository athttps://corp.example.com/repo.git orssh://corp.example.com/repo.git without needing to make additional requests.
Developers will need read access to repositories containing private modules.This may be configured in global VCS configuration files like.gitconfig.It’s best if VCS tools are configured not to need interactive authenticationprompts. By default, when invoking Git, thego command disables interactiveprompts by settingGIT_TERMINAL_PROMPT=0, but it respects explicit settings.
Passing credentials to private proxies
Thego command supports HTTPbasicauthentication whencommunicating with proxy servers.
Credentials may be specified in a.netrcfile.For example, a.netrc file containing the lines below would configure thegocommand to connect to the machineproxy.corp.example.com with the givenusername and password.
machine proxy.corp.example.comlogin jrgopherpassword hunter2The location of the file may be set with theNETRC environment variable. IfNETRC is not set, thego command will read$HOME/.netrc on UNIX-likeplatforms or%USERPROFILE%\_netrc on Windows.
Fields in.netrc are separated with spaces, tabs, and newlines. Unfortunately,these characters cannot be used in usernames or passwords. Note also that themachine name cannot be a full URL, so it’s not possible to specify differentusernames and passwords for different paths on the same machine.
Alternatively, credentials may be specified directly inGOPROXY URLs. Forexample:
GOPROXY=https://jrgopher:hunter2@proxy.corp.example.comUse caution when taking this approach: environment variables may appearin shell history and in logs.
Passing credentials to private repositories
Thego command may download a module directly from a version controlrepository. This is necessary for private modules if a private proxy isnot used. SeeDirect access to private modulesfor configuration.
Thego command runs version control tools likegit when downloadingmodules directly. These tools perform their own authentication, so you mayneed to configure credentials in a tool-specific configuration file like.gitconfig.
To ensure this works smoothly, make sure thego command uses the correctrepository URL and that the version control tool doesn’t require a password tobe entered interactively. Thego command prefershttps:// URLs over otherschemes likessh:// unless the scheme was specified whenlooking up therepository URL. For GitHub repositories specifically, thegocommand assumeshttps://.
For most servers, you can configure your client to authenticate over HTTP. Forexample, GitHub supports usingOAuth personal access tokens as HTTPpasswords.You can store HTTP passwords in a.netrc file, as whenpassing credentials toprivate proxies.
Alternatively, you can rewritehttps:// URLs to another scheme. For example,in.gitconfig:
[url "git@github.com:"] insteadOf = https://github.com/For more information, seeWhy does “go get” use HTTPS when cloning arepository?
Privacy
Thego command may download modules and metadata from module proxyservers and version control systems. The environment variableGOPROXYcontrols which servers are used. The environment variablesGOPRIVATE andGONOPROXY control which modules are fetched from proxies.
The default value ofGOPROXY is:
https://proxy.golang.org,directWith this setting, when thego command downloads a module or module metadata,it will first send a request toproxy.golang.org, a public module proxyoperated by Google (privacy policy). SeeGOPROXY protocol for details on what information is sentin each request. Thego command does not transmit personally identifiableinformation, but it does transmit the full module path being requested. If theproxy responds with a 404 (Not Found) or 410 (Gone) status, thego commandwill attempt to connect directly to the version control system providing themodule. SeeVersion control systems for details.
TheGOPRIVATE orGONOPROXY environment variables may be set to lists of globpatterns matching module prefixes that are private and should not be requestedfrom any proxy. For example:
GOPRIVATE=*.corp.example.com,*.research.example.comGOPRIVATE simply acts as a default forGONOPROXY andGONOSUMDB, so it’snot necessary to setGONOPROXY unlessGONOSUMDB should have a differentvalue. When a module path is matched byGONOPROXY, thego command ignoresGOPROXY for that module and fetches it directly from its version controlrepository. This is useful when no proxy serves private modules. SeeDirectaccess to private modules.
If there is atrusted proxy serving all modules,thenGONOPROXY should not be set. For example, ifGOPROXY is set to onesource, thego command will not download modules from other sources.GONOSUMDB should still be set in this situation.
GOPROXY=https://proxy.corp.example.comGONOSUMDB=*.corp.example.com,*.research.example.comIf there is atrusted proxy serving only privatemodules,GONOPROXY should not be set, but caremust be taken to ensure the proxy responds with the correct status codes. Forexample, consider the following configuration:
GOPROXY=https://proxy.corp.example.com,https://proxy.golang.orgGONOSUMDB=*.corp.example.com,*.research.example.comSuppose that due to a typo, a developer attempts to download a module thatdoesn’t exist.
go mod download corp.example.com/secret-product/typo@latestThego command first requests this module fromproxy.corp.example.com. Ifthat proxy responds with 404 (Not Found) or 410 (Gone), thego command willfall back toproxy.golang.org, transmitting thesecret-product path in therequest URL. If the private proxy responds with any other error code, thegocommand prints the error and will not fall back to other sources.
In addition to proxies, thego command may connect to the checksum database toverify cryptographic hashes of modules not listed ingo.sum. TheGOSUMDBenvironment variable sets the name, URL, and public key of the checksumdatabase. The default value ofGOSUMDB issum.golang.org, the publicchecksum database operated by Google (privacypolicy). SeeChecksumdatabase for details on what is transmitted with eachrequest. As with proxies, thego command does not transmit personallyidentifiable information, but it does transmit the full module path beingrequested, and the checksum database cannot compute checksums for non-publicmodules.
TheGONOSUMDB environment variable may be set to patterns indicating whichmodules are private and should not be requested from the checksumdatabase.GOPRIVATE acts as a default forGONOSUMDB andGONOPROXY, so it’snot necessary to setGONOSUMDB unlessGONOPROXY should have adifferent value.
A proxy maymirror the checksumdatabase.If a proxy inGOPROXY does this, thego command will not connect to thechecksum database directly.
GOSUMDB may be set tooff to disable use of the checksum databaseentirely. With this setting, thego command will not authenticate downloadedmodules unless they’re already ingo.sum. SeeAuthenticatingmodules.
Module cache
Themodule cache is the directory where thego command storesdownloaded module files. The module cache is distinct from the build cache,which contains compiled packages and other build artifacts.
The default location of the module cache is$GOPATH/pkg/mod. To use adifferent location, set theGOMODCACHEenvironmentvariable.
The module cache has no maximum size, and thego command does not remove itscontents automatically.
The cache may be shared by multiple Go projects developed on the same machine.Thego command will use the same cache regardless of the location of themain module. Multiple instances of thego command may safely access thesame module cache at the same time.
Thego command creates module source files and directories in the cache withread-only permissions to prevent accidental changes to modules after they’redownloaded. This has the unfortunate side-effect of making the cache difficultto delete with commands likerm -rf. The cache may instead be deleted withgo clean -modcache. Alternatively, when the-modcacherw flag is used, thego command will create new directories withread-write permissions. This increases the risk of editors, tests, and otherprograms modifying files in the module cache. Thego mod verify command may be used to detect modifications todependencies of the main module. It scans the extracted contents of eachmodule dependency and confirms they match the expected hash ingo.sum.
The table below explains the purpose of most files in the module cache. Sometransient files (lock files, temporary directories) are omitted. For each path,$module is a module path, and$version is a version. Paths ending withslashes (/) are directories. Capital letters in module paths and versions areescaped using exclamation points (Azure is escaped as!azure) to avoidconflicts on case-insensitive file systems.
| Path | Description |
|---|---|
$module@$version/ | Directory containing extracted contents of a module.zip file. This serves as a module root directory for a downloaded module. It won't contain ago.mod file if the original module didn't have one. |
cache/download/ | Directory containing files downloaded from module proxies and files derived fromversion control systems. The layout of this directory follows theGOPROXY protocol, so this directory may be used as a proxy when served by an HTTP file server or when referenced with afile:// URL. |
cache/download/$module/@v/list | List of known versions (seeGOPROXY protocol). This may change over time, so thego command usually fetches a new copy instead of re-using this file. |
cache/download/$module/@v/$version.info | JSON metadata about the version. (seeGOPROXY protocol). This may change over time, so thego command usually fetches a new copy instead of re-using this file. |
cache/download/$module/@v/$version.mod | Thego.mod file for this version (seeGOPROXY protocol). If the original module did not have ago.mod file, this is a synthesized file with no requirements. |
cache/download/$module/@v/$version.zip | The zipped contents of the module (seeGOPROXY protocol andModule zip files). |
cache/download/$module/@v/$version.ziphash | A cryptographic hash of the files in the.zip file. Note that the.zip file itself is not hashed, so file order, compression, alignment, and metadata don't affect the hash. When using a module, thego command verifies this hash matches the corresponding line ingo.sum. Thego mod verify command checks that the hashes of module.zip files and extracted directories match these files. |
cache/download/sumdb/ | Directory containing files downloaded from achecksum database (typicallysum.golang.org). |
cache/vcs/ | Contains cloned version control repositories for modules fetched directly from their sources. Directory names are hex-encoded hashes derived from the repository type and URL. Repositories are optimized for size on disk. For example, cloned Git repositories are bare and shallow when possible. |
Authenticating modules
When thego command downloads a modulezip file orgo.modfile into themodule cache, it computes acryptographic hash and compares it with a known value to verify the file hasn’tchanged since it was first downloaded. Thego command reports a security errorif a downloaded file does not have the correct hash.
Forgo.mod files, thego command computes the hash from the filecontent. For module zip files, thego command computes the hash from the namesand contents of files within the archive in a deterministic order. The hash isnot affected by file order, compression, alignment, and other metadata. Seegolang.org/x/mod/sumdb/dirhashfor hash implementation details.
Thego command compares each hash with the corresponding line in the mainmodule’sgo.sum file. If the hash is different from the hashingo.sum, thego command reports a security error and deletes thedownloaded file without adding it into the module cache.
If thego.sum file is not present, or if it doesn’t contain a hash for thedownloaded file, thego command may verify the hash using thechecksumdatabase, a global source of hashes for publicly availablemodules. Once the hash is verified, thego command adds it togo.sum andadds the downloaded file in the module cache. If a module is private (matched bytheGOPRIVATE orGONOSUMDB environment variables) or if the checksumdatabase is disabled (by settingGOSUMDB=off), thego command accepts thehash and adds the file to the module cache without verifying it.
The module cache is usually shared by all Go projects on a system, and eachmodule may have its owngo.sum file with potentially different hashes. Toavoid the need to trust other modules, thego command verifies hashes usingthe main module’sgo.sum whenever it accesses a file in the module cache. Zipfile hashes are expensive to compute, so thego command checks pre-computedhashes stored alongside zip files instead of re-hashing the files. Thego mod verify command may be used to check that zip files andextracted directories have not been modified since they were added to the modulecache.
go.sum files
A module may have a text file namedgo.sum in its root directory, alongsideitsgo.mod file. Thego.sum file contains cryptographic hashes of themodule’s direct and indirect dependencies. When thego command downloads amodule.mod or.zip file into themodule cache, it computesa hash and checks that the hash matches the corresponding hash in the mainmodule’sgo.sum file.go.sum may be empty or absent if the module has nodependencies or if all dependencies are replaced with local directories usingreplace directives.
Each line ingo.sum has three fields separated by spaces: a module path,a version (possibly ending with/go.mod), and a hash.
- The module path is the name of the module the hash belongs to.
- The version is the version of the module the hash belongs to. If the versionends with
/go.mod, the hash is for the module’sgo.modfile only;otherwise, the hash is for the files within the module’s.zipfile. - The hash column consists of an algorithm name (like
h1) and a base64-encodedcryptographic hash, separated by a colon (:). Currently, SHA-256 (h1) isthe only supported hash algorithm. If a vulnerability in SHA-256 is discoveredin the future, support will be added for another algorithm (namedh2andso on).
Thego.sum file may contain hashes for multiple versions of a module. Thegocommand may need to loadgo.mod files from multiple versions of a dependencyin order to performminimal version selection.go.sum may also contain hashes for module versions that aren’t needed anymore(for example, after an upgrade).go mod tidy will add missinghashes and will remove unnecessary hashes fromgo.sum.
Checksum database
The checksum database is a global source ofgo.sum lines. Thego command canuse this in many situations to detect misbehavior by proxies or origin servers.
The checksum database allows for global consistency and reliability for allpublicly available module versions. It makes untrusted proxies possible sincethey can’t serve the wrong code without it going unnoticed. It also ensuresthat the bits associated with a specific version do not change from one day tothe next, even if the module’s author subsequently alters the tags in theirrepository.
The checksum database is served bysum.golang.org,which is run by Google. It is aTransparentLog (or “Merkle Tree”) ofgo.sum linehashes, which is backed byTrillian. Themain advantage of a Merkle tree is that independent auditors can verify that ithasn’t been tampered with, so it is more trustworthy than a simple database.
Thego command interacts with the checksum database using the protocoloriginally outlined inProposal: Secure the Public Go ModuleEcosystem.
The table below specifies queries that the checksum database must respond to.For each path,$base is the path portion of the checksum database URL,$module is a module path, and$version is a version. For example, if thechecksum database URL ishttps://sum.golang.org, and the client is requestingthe record for the modulegolang.org/x/text at versionv0.3.2, the clientwould send aGET request forhttps://sum.golang.org/lookup/golang.org/x/text@v0.3.2.
To avoid ambiguity when serving from case-insensitive file systems,the$module and$version elements arecase-encodedby replacing every uppercase letter with an exclamation mark followed by thecorresponding lower-case letter. This allows modulesexample.com/M andexample.com/m to both be stored on disk, since the former is encoded asexample.com/!m.
Parts of the path surrounded by square brackets, like[.p/$W] denote optionalvalues.
| Path | Description |
|---|---|
$base/latest | Returns a signed, encoded tree description for the latest log. This signed description is in the form of anote, which is text that has been signed by one or more server keys and can be verified using the server's public key. The tree description provides the size of the tree and the hash of the tree head at that size. This encoding is described in golang.org/x/mod/sumdb/tlog#FormatTree. |
$base/lookup/$module@$version | Returns the log record number for the entry about$module at$version, followed by the data for the record (that is, thego.sum lines for$module at$version) and a signed, encoded tree description that contains the record. |
$base/tile/$H/$L/$K[.p/$W] | Returns a [log tile](https://research.swtch.com/tlog#serving_tiles), which is a set of hashes that make up a section of the log. Each tile is defined in a two-dimensional coordinate at tile level$L,$Kth from the left, with a tile height of$H. The optional.p/$W suffix indicates a partial log tile with only$W hashes. Clients must fall back to fetching the full tile if a partial tile is not found. |
$base/tile/$H/data/$K[.p/$W] | Returns the record data for the leaf hashes in/tile/$H/0/$K[.p/$W] (with a literaldata path element). |
If thego command consults the checksum database, then the firststep is to retrieve the record data through the/lookup endpoint. If themodule version is not yet recorded in the log, the checksum database will tryto fetch it from the origin server before replying. This/lookup dataprovides the sum for this module version as well as its position in the log,which informs the client of which tiles should be fetched to perform proofs.Thego command performs “inclusion” proofs (that a specific record exists inthe log) and “consistency” proofs (that the tree hasn’t been tampered with)before adding newgo.sum lines to the main module’sgo.sum file. It’simportant that the data from/lookup should never be used without firstauthenticating it against the signed tree hash and authenticating the signedtree hash against the client’s timeline of signed tree hashes.
Signed tree hashes and new tiles served by the checksum database are storedin the module cache, so thego command only needs to fetch tiles that aremissing.
Thego command doesn’t need to directly connect to the checksum database. Itcan request module sums via a module proxy thatmirrors the checksumdatabaseand supports the protocol above. This can be particularly helpful for private,corporate proxies which block requests outside the organization.
TheGOSUMDB environment variable identifies the name of checksum database touse and optionally its public key and URL, as in:
GOSUMDB="sum.golang.org"GOSUMDB="sum.golang.org+<publickey>"GOSUMDB="sum.golang.org+<publickey> https://sum.golang.org"Thego command knows the public key ofsum.golang.org, and also that thenamesum.golang.google.cn (available inside mainland China) connects to thesum.golang.org checksum database; use of any other database requires givingthe public key explicitly. The URL defaults tohttps:// followed by thedatabase name.
GOSUMDB defaults tosum.golang.org, the Go checksum database run by Google.Seehttps://sum.golang.org/privacy for the service’s privacy policy.
IfGOSUMDB is set tooff, or ifgo get is invoked with the-insecureflag, the checksum database is not consulted, and all unrecognized modules areaccepted, at the cost of giving up the security guarantee of verifiedrepeatable downloads for all modules. A better way to bypass the checksumdatabase for specific modules is to use theGOPRIVATE orGONOSUMDBenvironment variables. SeePrivate Modules for details.
Thego env -w command can be used toset these variablesfor futurego command invocations.
Environment variables
Module behavior in thego command may be configured using the environmentvariables listed below. This list only includes module-related environmentvariables. Seego help environment for a listof all environment variables recognized by thego command.
| Variable | Description |
|---|---|
GO111MODULE | Controls whether the
SeeModule-aware commands for more information. |
GOMODCACHE | The directory where the If |
GOINSECURE | Comma-separated list of glob patterns (in the syntax of Go's Unlike the |
GONOPROXY | Comma-separated list of glob patterns (in the syntax of Go's If |
GONOSUMDB | Comma-separated list of glob patterns (in the syntax of Go's If |
GOPATH | In In module-aware mode, themodule cache is stored in the If |
GOPRIVATE | Comma-separated list of glob patterns (in the syntax of Go'spath.Match) of module path prefixes that should be considered private.GOPRIVATE is a default value forGONOPROXY andGONOSUMDB. SeePrivacy.GOPRIVATE also determines whether a module is considered private forGOVCS. |
GOPROXY | List of module proxy URLs, separated by commas ( The
GOPROXY=file://$(go env GOMODCACHE)/cache/download Two keywords may be used in place of proxy URLs:
SeeModule proxies andResolving a package to a module for more information on how proxies are used. |
GOSUMDB | Identifies the name of the checksum database to use and optionally its public key and URL. For example: GOSUMDB="sum.golang.org"GOSUMDB="sum.golang.org+<publickey>"GOSUMDB="sum.golang.org+<publickey> https://sum.golang.org" The
If SeeAuthenticating modules andPrivacy for more information. |
GOVCS | Controls the set of version control tools the If public:git|hg,private:all SeeControlling version control tools with |
GOWORK | The `GOWORK` environment variable instructs the `go` command to enter workspace mode using the provided [`go.work` file](#go-work-file) to define the workspace. If `GOWORK` is set to `off` workspace mode is disabled. This can be used to run the `go` command in single module mode: for example, `GOWORK=off go build .` builds the `.` package in single-module mode.`If `GOWORK` is empty, the `go` command will search for a `go.work` file as described in the [Workspaces](#workspaces) section. |
Glossary
build constraint: A condition that determines whether a Go source file isused when compiling a package. Build constraints may be expressed with file namesuffixes (for example,foo_linux_amd64.go) or with build constraint comments(for example,// +build linux,amd64). SeeBuildConstraints.
build list: The list of module versions that will be used for a buildcommand such asgo build,go list, orgo test. The build list isdetermined from themain module’sgo.modfile andgo.mod files in transitively required modulesusingminimal version selection. The buildlist contains versions for all modules in themodulegraph, not just those relevant to a specific command.
canonical version: A correctly formattedversion withouta build metadata suffix other than+incompatible. For example,v1.2.3is a canonical version, butv1.2.3+meta is not.
current module: Synonym formain module.
deprecated module: A module that is no longer supported by its authors(though major versions are considered distinct modules for this purpose).A deprecated module is marked with adeprecationcomment in the latest version of itsgo.mod file.
direct dependency: A package whose path appears in animportdeclaration in a.go source file for a packageor test in themain module, or the module containing such apackage. (Compareindirect dependency.)
direct mode: A setting ofenvironment variablesthat causes thego command to download a module directly from aversioncontrol system, as opposed to amodule proxy.GOPROXY=direct does this for all modules.GOPRIVATE andGONOPROXY do thisfor modules matching a list of patterns.
go.mod file: The file that defines a module’s path, requirements, andother metadata. Appears in themodule’s rootdirectory. See the section ongo.modfiles.
go.work file The file that defines the set of modules to beused in aworkspace. See the section ongo.work files
import path: A string used to import a package in a Go source file.Synonymous withpackage path.
indirect dependency: A package transitively imported by a package or test inthemain module, but whose path does not appear in anyimport declaration in the main module;or a module that appears in themodule graph but does notprovide any package directly imported by the main module.(Comparedirect dependency.)
lazy module loading: A change in Go 1.17 that avoids loading themodulegraph for commands that do not need it in modules thatspecifygo 1.17 or higher. SeeLazy module loading.
main module: The module in which thego command is invoked. The mainmodule is defined by ago.mod file in the currentdirectory or a parent directory. SeeModules, packages, andversions.
major version: The first number in a semantic version (1 inv1.2.3). Ina release with incompatible changes, the major version must be incremented, andthe minor and patch versions must be set to 0. Semantic versions with majorversion 0 are considered unstable.
major version subdirectory: A subdirectory within a version controlrepository matching a module’smajor versionsuffix where a module may be defined. For example,the moduleexample.com/mod/v2 in the repository withrootpathexample.com/mod may be defined in therepository root directory or the major version subdirectoryv2. SeeModuledirectories within a repository.
major version suffix: A module path suffix that matches the major versionnumber. For example,/v2 inexample.com/mod/v2. Major version suffixes arerequired atv2.0.0 and later and are not allowed at earlier versions. Seethe section onMajor version suffixes.
minimal version selection (MVS): The algorithm used to determine theversions of all modules that will be used in a build. See the section onMinimal version selection for details.
minor version: The second number in a semantic version (2 inv1.2.3). Ina release with new, backwards compatible functionality, the minor version mustbe incremented, and the patch version must be set to 0.
module: A collection of packages that are released, versioned, anddistributed together.
module cache: A local directory storing downloaded modules, located inGOPATH/pkg/mod. SeeModule cache.
module graph: The directed graph of module requirements, rooted at themainmodule. Each vertex in the graph is a module; each edge is aversion from arequire statement in ago.mod file (subject toreplace andexclude statements in the main module’sgo.mod file).
module graph pruning: A change in Go 1.17 that reduces the size of themodule graph by omitting transitive dependencies of modules that specifygo 1.17 or higher. SeeModule graph pruning.
module path: A path that identifies a module and acts as a prefix forpackage import paths within the module. For example,"golang.org/x/net".
module proxy: A web server that implements theGOPROXYprotocol. Thego command downloads version information,go.mod files, and module zip files from module proxies.
module root directory: The directory that contains thego.mod file thatdefines a module.
module subdirectory: The portion of amodule path aftertherepository root path that indicates thesubdirectory where the module is defined. When non-empty, the modulesubdirectory is also a prefix forsemantic versiontags. The module subdirectory does not include themajor version suffix, if there is one, even if themodule is in amajor version subdirectory.SeeModule paths.
package: A collection of source files in the same directory that arecompiled together. See thePackages section in the GoLanguage Specification.
package path: The path that uniquely identifies a package. A package path isamodule path joined with a subdirectory within the module.For example"golang.org/x/net/html" is the package path for the package in themodule"golang.org/x/net" in the"html" subdirectory. Synonym ofimport path.
patch version: The third number in a semantic version (3 inv1.2.3). Ina release with no changes to the module’s public interface, the patch versionmust be incremented.
pre-release version: A version with a dash followed by a series ofdot-separated identifiers immediately following the patch version, for example,v1.2.3-beta4. Pre-release versions are considered unstable and are notassumed to be compatible with other versions. A pre-release version sorts beforethe corresponding release version:v1.2.3-pre comes beforev1.2.3. See alsorelease version.
pseudo-version: A version that encodes a revision identifier (such as a Gitcommit hash) and a timestamp from a version control system. For example,v0.0.0-20191109021931-daa7c04131f5. Used forcompatibility with non-modulerepositories and in other situations when a taggedversion is not available.
release version: A version without a pre-release suffix. For example,v1.2.3, notv1.2.3-pre. See alsopre-releaseversion.
repository root path: The portion of amodule path thatcorresponds to a version control repository’s root directory. SeeModulepaths.
retracted version: A version that should not be depended upon, eitherbecause it was published prematurely or because a severe problem was discoveredafter it was published. Seeretract directive.
semantic version tag: A tag in a version control repository that maps aversion to a specific revision. SeeMapping versions tocommits.
selected version: The version of a given module chosen byminimal versionselection. The selected version is the highestversion for the module’s path found in themodule graph.
vendor directory: A directory namedvendor that contains packages fromother modules needed to build packages in the main module. Maintained withgo mod vendor. SeeVendoring.
version: An identifier for an immutable snapshot of a module, written as theletterv followed by a semantic version. See the section onVersions.
workspace: A collection of modules on disk that are used asthe main modules when runningminimal version selection (MVS).See the section onWorkspaces