diff --git a/docs/usage/golang.md b/docs/usage/golang.md
index fc3e1d59b14578a7911923495d77bdb47a82a154..8c860e7997b2e354d495f10d85f8b91363a502cf 100644
--- a/docs/usage/golang.md
+++ b/docs/usage/golang.md
@@ -45,3 +45,22 @@ By default, Renovate will keep up with the very latest version of `go`.
 You can "pin" the `go` version that Renovate uses.
 Say you want Renovate to use Go version 1.14, you can do this by adding `go 1.14` to your `go.mod` file.
 We do not support pinning Go versions to a specific patch level, so you cannot use `go 1.14.12`, but you can use `go 1.14` in your `go.mod` file.
+
+### Custom registry support, and authentication
+
+This example shows how you can use a `config.js` file to configure Renovate for use with a custom private Go module source using Git to pull the modules.
+We're using environment variables to pass the Git token to Renovate bot.
+
+```js
+module.exports = {
+  hostRules: [
+    {
+      matchHost: 'github.enterprise.com',
+      token: process.env.GO_GIT_TOKEN,
+    },
+  ],
+  golang: {
+    registryUrls: ['github.enterprise.com'],
+  },
+};
+```
diff --git a/docs/usage/private-modules.md b/docs/usage/private-modules.md
index 87159f65ba7acf442ecb3eeac384a060a86b7bf5..ec245b912af6b2a7e029f60a2f05facd62a7548d 100644
--- a/docs/usage/private-modules.md
+++ b/docs/usage/private-modules.md
@@ -128,8 +128,11 @@ Any `hostRules` with `hostType=packagist` are also included.
 
 ### gomod
 
-If a `github.com` token is found in `hostRules`, then it is written out to local git config prior to running `go` commands.
-The command run is `git config --global url."https://${token}@github.com/".insteadOf "https://github.com/"`.
+The `GOPRIVATE` environment variable is used to decide if a package should be fetched from the `GOPROXY` or directly from the source.
+Most private modules will need to be fetched from the source directly, Renovate currently supports only Git for this.
+For each comma-separated module path in `GOPRIVATE` or `golang.registryUrls` Renovate will look for credentials in `hostRules`.
+Credentials are passed to Git via `GIT_CONFIG_KEY_x=url."https://${token}@${GOPRIVATE}/".insteadOf` and `GIT_CONFIG_VALUE_x=https://${GOPRIVATE}/` when running `go` commands.
+Glob syntax for `GOPRIVATE` is not supported.
 
 ### npm
 
diff --git a/lib/manager/gomod/__snapshots__/artifacts.spec.ts.snap b/lib/manager/gomod/__snapshots__/artifacts.spec.ts.snap
index 6e0ee06a4a9eb53fb7fcef28528b144b8ce1f9c0..a4ab89395c3458bc9228d92618da8267fbcfa2bf 100644
--- a/lib/manager/gomod/__snapshots__/artifacts.spec.ts.snap
+++ b/lib/manager/gomod/__snapshots__/artifacts.spec.ts.snap
@@ -13,6 +13,48 @@ Array [
 
 exports[`.updateArtifacts() catches errors 2`] = `Array []`;
 
+exports[`.updateArtifacts() ignore docker mode passthrough of invalid GIT_CONFIG_COUNT 1`] = `
+Array [
+  Object {
+    "cmd": "docker pull renovate/go:latest",
+    "options": Object {
+      "encoding": "utf-8",
+    },
+  },
+  Object {
+    "cmd": "docker ps --filter name=renovate_go -aq",
+    "options": Object {
+      "encoding": "utf-8",
+    },
+  },
+  Object {
+    "cmd": "docker run --rm --name=renovate_go --label=renovate_child -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GOPRIVATE -e GONOPROXY -e GONOSUMDB -e GOFLAGS -e CGO_ENABLED -w \\"/tmp/github/some/repo\\" renovate/go:latest bash -l -c \\"go get -d ./...\\"",
+    "options": Object {
+      "cwd": "/tmp/github/some/repo",
+      "encoding": "utf-8",
+      "env": Object {
+        "CGO_ENABLED": "1",
+        "GOFLAGS": "-modcacherw",
+        "GONOPROXY": "noproxy.example.com/*",
+        "GONOSUMDB": "1",
+        "GOPATH": "/tmp/renovate/cache/others/go",
+        "GOPRIVATE": "private.example.com/*",
+        "GOPROXY": "proxy.example.com",
+        "HOME": "/home/user",
+        "HTTPS_PROXY": "https://example.com",
+        "HTTP_PROXY": "http://example.com",
+        "LANG": "en_US.UTF-8",
+        "LC_ALL": "en_US",
+        "NO_PROXY": "localhost",
+        "PATH": "/tmp/path",
+      },
+      "maxBuffer": 10485760,
+      "timeout": 900000,
+    },
+  },
+]
+`;
+
 exports[`.updateArtifacts() returns if no go.sum found 1`] = `Array []`;
 
 exports[`.updateArtifacts() returns null if unchanged 1`] = `
@@ -269,7 +311,7 @@ Array [
 ]
 `;
 
-exports[`.updateArtifacts() supports docker mode with credentials 1`] = `
+exports[`.updateArtifacts() supports docker mode passthrough of GIT_CONFIG_COUNT 1`] = `
 Array [
   Object {
     "cmd": "docker pull renovate/go:latest",
@@ -284,12 +326,13 @@ Array [
     },
   },
   Object {
-    "cmd": "docker run --rm --name=renovate_go --label=renovate_child -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GOPRIVATE -e GONOPROXY -e GONOSUMDB -e GOFLAGS -e CGO_ENABLED -w \\"/tmp/github/some/repo\\" renovate/go:latest bash -l -c \\"git config --global url.\\\\\\"https://some-token@github.com/\\\\\\".insteadOf \\\\\\"https://github.com/\\\\\\" && go get -d ./...\\"",
+    "cmd": "docker run --rm --name=renovate_go --label=renovate_child -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GOPRIVATE -e GONOPROXY -e GONOSUMDB -e GOFLAGS -e CGO_ENABLED -e GIT_CONFIG_COUNT -w \\"/tmp/github/some/repo\\" renovate/go:latest bash -l -c \\"go get -d ./...\\"",
     "options": Object {
       "cwd": "/tmp/github/some/repo",
       "encoding": "utf-8",
       "env": Object {
         "CGO_ENABLED": "1",
+        "GIT_CONFIG_COUNT": "2",
         "GOFLAGS": "-modcacherw",
         "GONOPROXY": "noproxy.example.com/*",
         "GONOSUMDB": "1",
@@ -311,6 +354,149 @@ Array [
 ]
 `;
 
+exports[`.updateArtifacts() supports docker mode with credentials 1`] = `
+Array [
+  Object {
+    "cmd": "docker pull renovate/go:latest",
+    "options": Object {
+      "encoding": "utf-8",
+    },
+  },
+  Object {
+    "cmd": "docker ps --filter name=renovate_go -aq",
+    "options": Object {
+      "encoding": "utf-8",
+    },
+  },
+  Object {
+    "cmd": "docker run --rm --name=renovate_go --label=renovate_child -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GOPRIVATE -e GONOPROXY -e GONOSUMDB -e GOFLAGS -e CGO_ENABLED -e GIT_CONFIG_KEY_0 -e GIT_CONFIG_VALUE_0 -e GIT_CONFIG_COUNT -w \\"/tmp/github/some/repo\\" renovate/go:latest bash -l -c \\"go get -d ./...\\"",
+    "options": Object {
+      "cwd": "/tmp/github/some/repo",
+      "encoding": "utf-8",
+      "env": Object {
+        "CGO_ENABLED": "1",
+        "GIT_CONFIG_COUNT": "1",
+        "GIT_CONFIG_KEY_0": "url.https://some-token@github.com/.insteadOf",
+        "GIT_CONFIG_VALUE_0": "https://github.com/",
+        "GOFLAGS": "-modcacherw",
+        "GONOPROXY": "noproxy.example.com/*",
+        "GONOSUMDB": "1",
+        "GOPATH": "/tmp/renovate/cache/others/go",
+        "GOPRIVATE": "github.com",
+        "GOPROXY": "proxy.example.com",
+        "HOME": "/home/user",
+        "HTTPS_PROXY": "https://example.com",
+        "HTTP_PROXY": "http://example.com",
+        "LANG": "en_US.UTF-8",
+        "LC_ALL": "en_US",
+        "NO_PROXY": "localhost",
+        "PATH": "/tmp/path",
+      },
+      "maxBuffer": 10485760,
+      "timeout": 900000,
+    },
+  },
+]
+`;
+
+exports[`.updateArtifacts() supports docker mode with credentials with golang.registryUrls 1`] = `
+Array [
+  Object {
+    "cmd": "docker pull renovate/go:latest",
+    "options": Object {
+      "encoding": "utf-8",
+    },
+  },
+  Object {
+    "cmd": "docker ps --filter name=renovate_go -aq",
+    "options": Object {
+      "encoding": "utf-8",
+    },
+  },
+  Object {
+    "cmd": "docker run --rm --name=renovate_go --label=renovate_child -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GOPRIVATE -e GONOPROXY -e GONOSUMDB -e GOFLAGS -e CGO_ENABLED -e GIT_CONFIG_KEY_0 -e GIT_CONFIG_VALUE_0 -e GIT_CONFIG_COUNT -w \\"/tmp/github/some/repo\\" renovate/go:latest bash -l -c \\"go get -d ./...\\"",
+    "options": Object {
+      "cwd": "/tmp/github/some/repo",
+      "encoding": "utf-8",
+      "env": Object {
+        "CGO_ENABLED": "1",
+        "GIT_CONFIG_COUNT": "1",
+        "GIT_CONFIG_KEY_0": "url.https://some-token@github.com/.insteadOf",
+        "GIT_CONFIG_VALUE_0": "https://github.com/",
+        "GOFLAGS": "-modcacherw",
+        "GONOPROXY": "noproxy.example.com/*",
+        "GONOSUMDB": "1",
+        "GOPATH": "/tmp/renovate/cache/others/go",
+        "GOPRIVATE": "github.com,github.enterprise.com/test,github2.enterprise.com",
+        "GOPROXY": "proxy.example.com",
+        "HOME": "/home/user",
+        "HTTPS_PROXY": "https://example.com",
+        "HTTP_PROXY": "http://example.com",
+        "LANG": "en_US.UTF-8",
+        "LC_ALL": "en_US",
+        "NO_PROXY": "localhost",
+        "PATH": "/tmp/path",
+      },
+      "maxBuffer": 10485760,
+      "timeout": 900000,
+    },
+  },
+]
+`;
+
+exports[`.updateArtifacts() supports docker mode with custom credentials 1`] = `
+Array [
+  Object {
+    "cmd": "docker pull renovate/go:latest",
+    "options": Object {
+      "encoding": "utf-8",
+    },
+  },
+  Object {
+    "cmd": "docker ps --filter name=renovate_go -aq",
+    "options": Object {
+      "encoding": "utf-8",
+    },
+  },
+  Object {
+    "cmd": "docker run --rm --name=renovate_go --label=renovate_child -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GOPRIVATE -e GONOPROXY -e GONOSUMDB -e GOFLAGS -e CGO_ENABLED -e GIT_CONFIG_KEY_0 -e GIT_CONFIG_VALUE_0 -e GIT_CONFIG_COUNT -e GIT_CONFIG_KEY_1 -e GIT_CONFIG_VALUE_1 -e GIT_CONFIG_KEY_2 -e GIT_CONFIG_VALUE_2 -e GIT_CONFIG_KEY_3 -e GIT_CONFIG_VALUE_3 -e GIT_CONFIG_KEY_4 -e GIT_CONFIG_VALUE_4 -w \\"/tmp/github/some/repo\\" renovate/go:latest bash -l -c \\"go get -d ./...\\"",
+    "options": Object {
+      "cwd": "/tmp/github/some/repo",
+      "encoding": "utf-8",
+      "env": Object {
+        "CGO_ENABLED": "1",
+        "GIT_CONFIG_COUNT": "5",
+        "GIT_CONFIG_KEY_0": "url.https://some-github-enterprise-token@github.enterprise.com/.insteadOf",
+        "GIT_CONFIG_KEY_1": "url.https://some-git-private-token@git.private.com/.insteadOf",
+        "GIT_CONFIG_KEY_2": "url.https://some-git2-private-token@git2.private.com/.insteadOf",
+        "GIT_CONFIG_KEY_3": "url.https://some-git3-private-token@git3.private.com/test-org.insteadOf",
+        "GIT_CONFIG_KEY_4": "url.https://username:password@git4.private.com/.insteadOf",
+        "GIT_CONFIG_VALUE_0": "https://github.enterprise.com/",
+        "GIT_CONFIG_VALUE_1": "https://git.private.com/",
+        "GIT_CONFIG_VALUE_2": "https://git2.private.com/",
+        "GIT_CONFIG_VALUE_3": "https://git3.private.com/test-org",
+        "GIT_CONFIG_VALUE_4": "https://git4.private.com/",
+        "GOFLAGS": "-modcacherw",
+        "GONOPROXY": "noproxy.example.com/*",
+        "GONOSUMDB": "1",
+        "GOPATH": "/tmp/renovate/cache/others/go",
+        "GOPRIVATE": "github.enterprise.com,git.private.com,git2.private.com,git3.private.com/test-org,git4.private.com,git5.private.com",
+        "GOPROXY": "proxy.example.com",
+        "HOME": "/home/user",
+        "HTTPS_PROXY": "https://example.com",
+        "HTTP_PROXY": "http://example.com",
+        "LANG": "en_US.UTF-8",
+        "LC_ALL": "en_US",
+        "NO_PROXY": "localhost",
+        "PATH": "/tmp/path",
+      },
+      "maxBuffer": 10485760,
+      "timeout": 900000,
+    },
+  },
+]
+`;
+
 exports[`.updateArtifacts() supports docker mode with goModTidy 1`] = `
 Array [
   Object {
@@ -353,6 +539,47 @@ Array [
 ]
 `;
 
+exports[`.updateArtifacts() supports docker mode without GORPIVATE 1`] = `
+Array [
+  Object {
+    "cmd": "docker pull renovate/go:latest",
+    "options": Object {
+      "encoding": "utf-8",
+    },
+  },
+  Object {
+    "cmd": "docker ps --filter name=renovate_go -aq",
+    "options": Object {
+      "encoding": "utf-8",
+    },
+  },
+  Object {
+    "cmd": "docker run --rm --name=renovate_go --label=renovate_child -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GONOPROXY -e GONOSUMDB -e GOFLAGS -e CGO_ENABLED -w \\"/tmp/github/some/repo\\" renovate/go:latest bash -l -c \\"go get -d ./...\\"",
+    "options": Object {
+      "cwd": "/tmp/github/some/repo",
+      "encoding": "utf-8",
+      "env": Object {
+        "CGO_ENABLED": "1",
+        "GOFLAGS": "-modcacherw",
+        "GONOPROXY": "noproxy.example.com/*",
+        "GONOSUMDB": "1",
+        "GOPATH": "/tmp/renovate/cache/others/go",
+        "GOPROXY": "proxy.example.com",
+        "HOME": "/home/user",
+        "HTTPS_PROXY": "https://example.com",
+        "HTTP_PROXY": "http://example.com",
+        "LANG": "en_US.UTF-8",
+        "LC_ALL": "en_US",
+        "NO_PROXY": "localhost",
+        "PATH": "/tmp/path",
+      },
+      "maxBuffer": 10485760,
+      "timeout": 900000,
+    },
+  },
+]
+`;
+
 exports[`.updateArtifacts() supports docker mode without credentials 1`] = `
 Array [
   Object {
diff --git a/lib/manager/gomod/artifacts.spec.ts b/lib/manager/gomod/artifacts.spec.ts
index f9b5e52e0eb887ab53d28eadc85739c8738b1e4d..f1b5d0a3f4315349e8acdc11041b063d8aa28f09 100644
--- a/lib/manager/gomod/artifacts.spec.ts
+++ b/lib/manager/gomod/artifacts.spec.ts
@@ -49,7 +49,6 @@ const config: UpdateArtifactsConfig = {
 const goEnv = {
   GONOSUMDB: '1',
   GOPROXY: 'proxy.example.com',
-  GOPRIVATE: 'private.example.com/*',
   GONOPROXY: 'noproxy.example.com/*',
   CGO_ENABLED: '1',
 };
@@ -60,13 +59,17 @@ describe('.updateArtifacts()', () => {
     jest.resetModules();
 
     delete process.env.GOPATH;
+    delete process.env.GIT_CONFIG_COUNT;
+    process.env.GOPRIVATE = 'private.example.com/*';
     env.getChildProcessEnv.mockReturnValue({ ...envMock.basic, ...goEnv });
     setAdminConfig(adminConfig);
     docker.resetPrefetchedImages();
   });
+
   afterEach(() => {
     setAdminConfig();
   });
+
   it('returns if no go.sum found', async () => {
     const execSnapshots = mockExecAll(exec);
     expect(
@@ -79,6 +82,7 @@ describe('.updateArtifacts()', () => {
     ).toBeNull();
     expect(execSnapshots).toMatchSnapshot();
   });
+
   it('returns null if unchanged', async () => {
     fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
     fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
@@ -96,6 +100,7 @@ describe('.updateArtifacts()', () => {
     ).toBeNull();
     expect(execSnapshots).toMatchSnapshot();
   });
+
   it('returns updated go.sum', async () => {
     fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
     fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
@@ -114,6 +119,7 @@ describe('.updateArtifacts()', () => {
     ).not.toBeNull();
     expect(execSnapshots).toMatchSnapshot();
   });
+
   it('supports vendor directory update', async () => {
     const foo = join('vendor/github.com/foo/foo/go.mod');
     const bar = join('vendor/github.com/bar/bar/go.mod');
@@ -150,6 +156,7 @@ describe('.updateArtifacts()', () => {
     ]);
     expect(execSnapshots).toMatchSnapshot();
   });
+
   it('supports docker mode without credentials', async () => {
     setAdminConfig({ ...adminConfig, binarySource: 'docker' });
     fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
@@ -169,6 +176,70 @@ describe('.updateArtifacts()', () => {
     ).not.toBeNull();
     expect(execSnapshots).toMatchSnapshot();
   });
+
+  it('supports docker mode passthrough of GIT_CONFIG_COUNT', async () => {
+    process.env.GIT_CONFIG_COUNT = '2';
+    setAdminConfig({ ...adminConfig, binarySource: 'docker' });
+    fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
+    fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
+    const execSnapshots = mockExecAll(exec);
+    git.getRepoStatus.mockResolvedValueOnce({
+      modified: ['go.sum'],
+    } as StatusResult);
+    fs.readFile.mockResolvedValueOnce('New go.sum' as any);
+    expect(
+      await gomod.updateArtifacts({
+        packageFileName: 'go.mod',
+        updatedDeps: [],
+        newPackageFileContent: gomod1,
+        config,
+      })
+    ).not.toBeNull();
+    expect(execSnapshots).toMatchSnapshot();
+  });
+
+  it('supports docker mode without GORPIVATE', async () => {
+    delete process.env.GOPRIVATE;
+    setAdminConfig({ ...adminConfig, binarySource: 'docker' });
+    fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
+    fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
+    const execSnapshots = mockExecAll(exec);
+    git.getRepoStatus.mockResolvedValueOnce({
+      modified: ['go.sum'],
+    } as StatusResult);
+    fs.readFile.mockResolvedValueOnce('New go.sum' as any);
+    expect(
+      await gomod.updateArtifacts({
+        packageFileName: 'go.mod',
+        updatedDeps: [],
+        newPackageFileContent: gomod1,
+        config,
+      })
+    ).not.toBeNull();
+    expect(execSnapshots).toMatchSnapshot();
+  });
+
+  it('ignore docker mode passthrough of invalid GIT_CONFIG_COUNT', async () => {
+    process.env.GIT_CONFIG_COUNT = 'not-a-number';
+    setAdminConfig({ ...adminConfig, binarySource: 'docker' });
+    fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
+    fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
+    const execSnapshots = mockExecAll(exec);
+    git.getRepoStatus.mockResolvedValueOnce({
+      modified: ['go.sum'],
+    } as StatusResult);
+    fs.readFile.mockResolvedValueOnce('New go.sum' as any);
+    expect(
+      await gomod.updateArtifacts({
+        packageFileName: 'go.mod',
+        updatedDeps: [],
+        newPackageFileContent: gomod1,
+        config,
+      })
+    ).not.toBeNull();
+    expect(execSnapshots).toMatchSnapshot();
+  });
+
   it('supports global mode', async () => {
     setAdminConfig({ ...adminConfig, binarySource: 'global' });
     fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
@@ -188,7 +259,33 @@ describe('.updateArtifacts()', () => {
     ).not.toBeNull();
     expect(execSnapshots).toMatchSnapshot();
   });
+
   it('supports docker mode with credentials', async () => {
+    setAdminConfig({ ...adminConfig, binarySource: 'docker' });
+    process.env.GOPRIVATE = 'github.com';
+    hostRules.find.mockReturnValueOnce({
+      token: 'some-token',
+    });
+    fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
+    fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
+    const execSnapshots = mockExecAll(exec);
+    git.getRepoStatus.mockResolvedValueOnce({
+      modified: ['go.sum'],
+    } as StatusResult);
+    fs.readFile.mockResolvedValueOnce('New go.sum' as any);
+    expect(
+      await gomod.updateArtifacts({
+        packageFileName: 'go.mod',
+        updatedDeps: [],
+        newPackageFileContent: gomod1,
+        config,
+      })
+    ).not.toBeNull();
+    expect(execSnapshots).toMatchSnapshot();
+  });
+
+  it('supports docker mode with credentials with golang.registryUrls', async () => {
+    delete process.env.GOPRIVATE;
     setAdminConfig({ ...adminConfig, binarySource: 'docker' });
     hostRules.find.mockReturnValueOnce({
       token: 'some-token',
@@ -200,6 +297,66 @@ describe('.updateArtifacts()', () => {
       modified: ['go.sum'],
     } as StatusResult);
     fs.readFile.mockResolvedValueOnce('New go.sum' as any);
+    expect(
+      await gomod.updateArtifacts({
+        packageFileName: 'go.mod',
+        updatedDeps: [],
+        newPackageFileContent: gomod1,
+        config: {
+          ...config,
+          registryUrls: [
+            'github.com',
+            'github.enterprise.com/test',
+            'https://github2.enterprise.com',
+            'ftp://this-is-invalid.git.enterprise.com',
+          ],
+        },
+      })
+    ).not.toBeNull();
+    expect(execSnapshots).toMatchSnapshot();
+  });
+
+  it('supports docker mode with custom credentials', async () => {
+    setAdminConfig({ ...adminConfig, binarySource: 'docker' });
+    const mockValues = [
+      {
+        token: 'some-github-enterprise-token',
+        matchHost: 'github.enterprise.com',
+      },
+      {
+        token: 'some-git-private-token',
+        matchHost: 'git.private.com',
+      },
+      {
+        token: 'some-git2-private-token',
+        matchHost: 'https://git2.private.com',
+      },
+      {
+        token: 'some-git3-private-token',
+        matchHost: 'git3.private.com/test-org',
+      },
+      {
+        username: 'username',
+        password: 'password',
+        matchHost: 'git4.private.com',
+      },
+      {
+        username: 'username-is-not-enough',
+        matchHost: 'git5.private.com',
+      },
+    ];
+    process.env.GOPRIVATE =
+      'github.enterprise.com,git.private.com,git2.private.com,git3.private.com/test-org,git4.private.com,git5.private.com';
+    for (const mockValue of mockValues) {
+      hostRules.find.mockReturnValueOnce(mockValue);
+    }
+    fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
+    fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
+    const execSnapshots = mockExecAll(exec);
+    git.getRepoStatus.mockResolvedValueOnce({
+      modified: ['go.sum'],
+    } as StatusResult);
+    fs.readFile.mockResolvedValueOnce('New go.sum' as any);
     expect(
       await gomod.updateArtifacts({
         packageFileName: 'go.mod',
@@ -210,6 +367,7 @@ describe('.updateArtifacts()', () => {
     ).not.toBeNull();
     expect(execSnapshots).toMatchSnapshot();
   });
+
   it('supports docker mode with goModTidy', async () => {
     setAdminConfig({ ...adminConfig, binarySource: 'docker' });
     hostRules.find.mockReturnValueOnce({});
@@ -236,6 +394,7 @@ describe('.updateArtifacts()', () => {
     ).not.toBeNull();
     expect(execSnapshots).toMatchSnapshot();
   });
+
   it('catches errors', async () => {
     const execSnapshots = mockExecAll(exec);
     fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
@@ -253,6 +412,7 @@ describe('.updateArtifacts()', () => {
     ).toMatchSnapshot();
     expect(execSnapshots).toMatchSnapshot();
   });
+
   it('updates import paths with gomodUpdateImportPaths', async () => {
     fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
     fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
@@ -279,6 +439,7 @@ describe('.updateArtifacts()', () => {
     ).toMatchSnapshot();
     expect(execSnapshots).toMatchSnapshot();
   });
+
   it('skips updating import paths with gomodUpdateImportPaths on v0 to v1', async () => {
     fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
     fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
@@ -304,6 +465,7 @@ describe('.updateArtifacts()', () => {
     ).toMatchSnapshot();
     expect(execSnapshots).toMatchSnapshot();
   });
+
   it('updates import paths with specific tool version from constraint', async () => {
     fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
     fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
@@ -333,6 +495,7 @@ describe('.updateArtifacts()', () => {
     ).toMatchSnapshot();
     expect(execSnapshots).toMatchSnapshot();
   });
+
   it('updates import paths with latest tool version on invalid version constraint', async () => {
     fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
     fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
@@ -362,6 +525,7 @@ describe('.updateArtifacts()', () => {
     ).toMatchSnapshot();
     expect(execSnapshots).toMatchSnapshot();
   });
+
   it('skips updating import paths for gopkg.in dependencies', async () => {
     fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
     fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
diff --git a/lib/manager/gomod/artifacts.ts b/lib/manager/gomod/artifacts.ts
index 36f05c0983457cf7063a5c10c1c540c4be055172..6e611233dfb815ed12c6f036942316d63b6eb71d 100644
--- a/lib/manager/gomod/artifacts.ts
+++ b/lib/manager/gomod/artifacts.ts
@@ -1,14 +1,14 @@
 import is from '@sindresorhus/is';
-import { quote } from 'shlex';
 import { dirname, join } from 'upath';
 import { getAdminConfig } from '../../config/admin';
 import { TEMPORARY_ERROR } from '../../constants/error-messages';
-import { PLATFORM_TYPE_GITHUB } from '../../constants/platforms';
 import { logger } from '../../logger';
 import { ExecOptions, exec } from '../../util/exec';
 import { ensureCacheDir, readLocalFile, writeLocalFile } from '../../util/fs';
 import { getRepoStatus } from '../../util/git';
-import { find } from '../../util/host-rules';
+import { getGitAuthenticatedEnvironmentVariables } from '../../util/git/auth';
+import { getHttpUrl } from '../../util/git/url';
+import { parseUrl } from '../../util/url';
 import { isValid } from '../../versioning/semver';
 import type {
   PackageDependency,
@@ -17,19 +17,18 @@ import type {
   UpdateArtifactsResult,
 } from '../types';
 
-function getPreCommands(): string[] | null {
-  const credentials = find({
-    hostType: PLATFORM_TYPE_GITHUB,
-    url: 'https://api.github.com/',
-  });
-  let preCommands = null;
-  if (credentials?.token) {
-    const token = quote(credentials.token);
-    preCommands = [
-      `git config --global url.\"https://${token}@github.com/\".insteadOf \"https://github.com/\"`, // eslint-disable-line no-useless-escape
-    ];
+function getGoEnvironmentVariables(registryUrls: string[]): NodeJS.ProcessEnv {
+  let goEnvVariables: NodeJS.ProcessEnv = {};
+
+  for (const registryUrl of registryUrls) {
+    const goPrivateWithProtocol = getHttpUrl(registryUrl);
+    goEnvVariables = getGitAuthenticatedEnvironmentVariables(
+      goPrivateWithProtocol,
+      goEnvVariables
+    );
   }
-  return preCommands;
+
+  return goEnvVariables;
 }
 
 function getUpdateImportPathCmds(
@@ -116,6 +115,51 @@ export async function updateArtifacts({
       logger.debug('Removed some relative replace statements from go.mod');
     }
     await writeLocalFile(goModFileName, massagedGoMod);
+    // array of GOMODULE registries which should be fetched from
+    // passed to go as GOPRIVATE
+    let registryUrls: string[] = [];
+    let goPrivates: string[] = [];
+
+    // add GOPRIVATE environment variables
+    if (process.env.GOPRIVATE) {
+      goPrivates = process.env.GOPRIVATE.split(',');
+      // GOPRIVATE is without protocol so we add the https protocol before adding it to the registryUrls
+      const goPrivatesWithProtocol = goPrivates.map(
+        (goPrivate) => `https://${goPrivate}`
+      );
+      registryUrls = registryUrls.concat(goPrivatesWithProtocol);
+    }
+
+    // add explicit registryUrls
+    if (config.registryUrls) {
+      for (const registryUrl of config.registryUrls) {
+        // if the registryUrl could not be parsed, retry with a protocol
+        const parsedRegistryUrl =
+          parseUrl(registryUrl) || parseUrl(`https://${registryUrl}`);
+
+        // Only allow http(s)
+        if (parsedRegistryUrl?.protocol?.startsWith('http')) {
+          // Add the full URL to the registryUrls
+          registryUrls.push(parsedRegistryUrl.toString());
+
+          // Add only the domain + path to the goPrivates
+          let goPrivate = parsedRegistryUrl.host;
+          // only add the pathname if it is not just the base path
+          if (parsedRegistryUrl.pathname !== '/') {
+            goPrivate += parsedRegistryUrl.pathname;
+          }
+          goPrivates.push(goPrivate);
+        } else {
+          // ignore if registryUrl could not be parsed
+          logger.warn(
+            `Could not parse registryUrl ${registryUrl} or not using http(s). Ignoring`
+          );
+        }
+      }
+    }
+
+    // create comma-separated GOPRIVATE environment variable if any goPrivates exist
+    const goPrivate = goPrivates.length > 0 ? goPrivates.join(',') : undefined;
 
     const cmd = 'go';
     const execOptions: ExecOptions = {
@@ -123,18 +167,18 @@ export async function updateArtifacts({
       extraEnv: {
         GOPATH: goPath,
         GOPROXY: process.env.GOPROXY,
-        GOPRIVATE: process.env.GOPRIVATE,
+        GOPRIVATE: goPrivate,
         GONOPROXY: process.env.GONOPROXY,
         GONOSUMDB: process.env.GONOSUMDB,
         GOFLAGS: useModcacherw(config.constraints?.go) ? '-modcacherw' : null,
         CGO_ENABLED: getAdminConfig().binarySource === 'docker' ? '0' : null,
+        ...getGoEnvironmentVariables(registryUrls),
       },
       docker: {
         image: 'go',
         tagConstraint: config.constraints?.go,
         tagScheme: 'npm',
         volumes: [goPath],
-        preCommands: getPreCommands(),
       },
     };
 
diff --git a/lib/util/git/auth.ts b/lib/util/git/auth.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4cfba38e4ffaae8dd21f97794331062ca1b4845b
--- /dev/null
+++ b/lib/util/git/auth.ts
@@ -0,0 +1,43 @@
+import { logger } from '../../logger';
+import { getRemoteUrlWithToken } from './url';
+
+/*
+    Add authorization to a Git Url and returns the updated environment variables
+*/
+export function getGitAuthenticatedEnvironmentVariables(
+  gitUrl: string,
+  environmentVariables: NodeJS.ProcessEnv
+): NodeJS.ProcessEnv {
+  // check if the environmentVariables already contain a GIT_CONFIG_COUNT or if the process has one
+  const gitConfigCountEnvVariable =
+    environmentVariables.GIT_CONFIG_COUNT || process.env.GIT_CONFIG_COUNT;
+  let gitConfigCount = 0;
+  if (gitConfigCountEnvVariable) {
+    // passthrough the gitConfigCountEnvVariable environment variable as start value of the index count
+    gitConfigCount = parseInt(gitConfigCountEnvVariable, 10);
+    if (Number.isNaN(gitConfigCount)) {
+      logger.warn(
+        `Found GIT_CONFIG_COUNT env variable, but couldn't parse the value to an integer: ${process.env.GIT_CONFIG_COUNT}. Ignoring it.`
+      );
+      gitConfigCount = 0;
+    }
+  }
+
+  const gitUrlWithToken = getRemoteUrlWithToken(gitUrl);
+  const returnEnvironmentVariables = { ...environmentVariables };
+
+  // only if credentials got injected and thus the urls are no longer equal
+  if (gitUrlWithToken !== gitUrl) {
+    // prettier-ignore
+    returnEnvironmentVariables[`GIT_CONFIG_KEY_${gitConfigCount}`] = `url.${gitUrlWithToken}.insteadOf`;
+    // prettier-ignore
+    returnEnvironmentVariables[`GIT_CONFIG_VALUE_${gitConfigCount}`] = gitUrl;
+    gitConfigCount += 1;
+  }
+
+  if (gitConfigCount > 0) {
+    returnEnvironmentVariables.GIT_CONFIG_COUNT = gitConfigCount.toString();
+  }
+
+  return returnEnvironmentVariables;
+}