Problem Description

After executing go clean -modcache locally, executing go mod download gives the following error.

1
2
3
4
verifying git.xxx.com/neirong/app-framework@v0.7.8/go.mod: checksum mismatch
	downloaded: h1:/8A+C1sjRPdK/06I7b2egOVjo8+ECKV3vJ3Cqz5vEzc=
	go.sum:     h1:7HfHuMOcinPkTDMNEf6Otcy4+TBvDQ/+f2UO0N23l3o=
SECURITY ERROR

If you encounter a checksum mismatch error, delete go.sum, execute go clean -modcache, and then execute go mod download. That’s what I did, and after that, no more errors were reported. When I commit the new go.sum file to GitLab, I get the same error when I run it to lint.

1
2
3
4
verifying git.xxx.com/neirong/app-framework@v0.7.8/go.mod: checksum mismatch
	downloaded: h1:/8A+C1sjRPdK/06I7b2egOVjo8+ECKV3vJ3Cqz5vEzc=
	go.sum:     h1:7HfHuMOcinPkTDMNEf6Otcy4+TBvDQ/+f2UO0N23l3o=
SECURITY ERROR

That is, the hash (old) calculated after downloading from app-framework@v0.7.8/go.mod does not match the hash (new) in the newly generated go.sum.

Solution Process

  1. determine if GitLab has a module cache when running lint, and conclude that GitLab is running a new container with no cache

  2. Because go env’s proxy is set to the company’s proxy address, and app-framework@v0.7.8 is a private module, consider that the proxy has an old cache for that module. However, if we find other colleagues, delete go.sum, execute go clean -modcache, and then execute go mod download, the hash of app-framework@v0.7.8 in the new go.sum is still old, which means that the hash obtained by different people performing the same operation is not the same.

  3. Using the go-checksum tool, I manually computed the hash of the app-framework@v0.7.8 module to make sure that the hash I generated later was correct:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    ~/temp/app-framework  go-checksum go.mod
    file: go.mod
    {
        "Hash": "3efa7cc5648863b16b19e6e8b781f40bf4d0e95137b5a5f97e6468a00dc3f45a",
        "HashBase64": "Pvp8xWSIY7FrGebot4H0C/TQ6VE3taX5fmRooA3D9Fo=",
        "HashSynthesized": "ec77c7b8c39c8a73e44c330d11fe8eb5ccb8f9306f0d0ffe7f650ed0ddb7977a",
        "HashSynthesizedBase64": "7HfHuMOcinPkTDMNEf6Otcy4+TBvDQ/+f2UO0N23l3o=",
        "GoCheckSum": "h1:7HfHuMOcinPkTDMNEf6Otcy4+TBvDQ/+f2UO0N23l3o="
    }
    
  4. The problem was solved by clearing the proxy cache and GitLab’s lint no longer reporting errors.

Q & A

1. What causes the hash inconsistency in the go.sum file for the same version of the module?

If there is no corresponding tag, find the branch with the same name of the specified version, and if you find the branch with the same name, pull it directly. If there is a branch first, it will be cached on the proxy after someone pulls it through the proxy. If the module is modified on the branch afterwards and then tagged, the module file will be changed and the hash will be changed with it, and the proxy will always cache the old module.

2. How can I avoid the problem in 1?

Don’t use the same branch name as the tag to prevent others from using a version that is not officially released.

3. Since the proxy caches old modules, why do different people delete the go.sum file, run go clean -modcache, and then run go mod download when some people still have the old modules and some people get the new ones?

This is because of the gonoproxy environment variable in go env. My local GONOPROXY=“git.xxx.com”, that is, to download the modules on git.xxx.com, not to go through the proxy, directly from the source site.If there is no git.xxx.com content set in the gonoproxy environment variable, it will be fetched from the proxy (hitting the old cache).

GONOPROXY official definition.

GONOPROXY — list of glob patterns of module path prefixes that should not be downloaded from a proxy. The go command will download matching modules from version control repositories where they’re developed, regardless of GOPROXY.