diff --git a/lib/datasource/nuget/__snapshots__/index.spec.ts.snap b/lib/datasource/nuget/__snapshots__/index.spec.ts.snap
index b6838ca6640c5177c07a821006b8fad799760ed8..f0f6fba5dcc81d08f022c394e04d81a0f0ec584c 100644
--- a/lib/datasource/nuget/__snapshots__/index.spec.ts.snap
+++ b/lib/datasource/nuget/__snapshots__/index.spec.ts.snap
@@ -518,6 +518,16 @@ Array [
     "method": "GET",
     "url": "https://api.nuget.org/v3/registration5-gz-semver2/nunit/index.json",
   },
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate",
+      "host": "api.nuget.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://api.nuget.org/v3/index.json",
+  },
   Object {
     "headers": Object {
       "accept-encoding": "gzip, deflate",
@@ -561,7 +571,6 @@ Object {
       "version": "2.6.1",
     },
     Object {
-      "releaseTimestamp": "2012-10-23T15:37:48+00:00",
       "version": "2.6.2",
     },
     Object {
@@ -743,6 +752,25 @@ Array [
     "method": "GET",
     "url": "https://api.nuget.org/v3/registration5-gz-semver2/nunit/index.json",
   },
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate",
+      "host": "myprivatefeed",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://myprivatefeed/index.json",
+  },
+  Object {
+    "headers": Object {
+      "accept-encoding": "gzip, deflate",
+      "host": "api.nuget.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://api.nuget.org/v3-flatcontainer/nunit/3.12.0/nunit.nuspec",
+  },
 ]
 `;
 
@@ -1520,6 +1548,16 @@ Array [
     "method": "GET",
     "url": "https://api.nuget.org/v3/registration5-gz-semver2/nlog/page/4.6.0-rc3/5.0.0-beta11.json",
   },
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate",
+      "host": "api.nuget.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://api.nuget.org/v3/index.json",
+  },
   Object {
     "headers": Object {
       "accept-encoding": "gzip, deflate",
@@ -1936,6 +1974,16 @@ Array [
     "method": "GET",
     "url": "https://api.nuget.org/v3/registration5-gz-semver2/nunit/index.json",
   },
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate",
+      "host": "api.nuget.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://api.nuget.org/v3/index.json",
+  },
   Object {
     "headers": Object {
       "accept-encoding": "gzip, deflate",
@@ -1965,6 +2013,25 @@ Array [
     "method": "GET",
     "url": "https://api.nuget.org/v3/registration5-gz-semver2/nunit/index.json",
   },
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate",
+      "host": "myprivatefeed",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://myprivatefeed/index.json",
+  },
+  Object {
+    "headers": Object {
+      "accept-encoding": "gzip, deflate",
+      "host": "api.nuget.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://api.nuget.org/v3-flatcontainer/nunit/3.12.0/nunit.nuspec",
+  },
 ]
 `;
 
diff --git a/lib/datasource/nuget/index.spec.ts b/lib/datasource/nuget/index.spec.ts
index c7a3ab2025ce40ca3fb18ddad0fd165802d4065e..9e5bcb2a4053fc8b1f6849296e8272e7f4ee101a 100644
--- a/lib/datasource/nuget/index.spec.ts
+++ b/lib/datasource/nuget/index.spec.ts
@@ -307,8 +307,10 @@ describe('datasource/nuget', () => {
       httpMock
         .scope('https://api.nuget.org')
         .get('/v3/index.json')
+        .twice()
         .reply(200, JSON.parse(nugetIndexV3))
         .get('/v3-flatcontainer/nunit/3.12.0/nunit.nuspec')
+        .twice()
         .reply(200, pkgInfoV3FromNuget)
         .get('/v3/registration5-gz-semver2/nunit/index.json')
         .twice()
@@ -316,6 +318,7 @@ describe('datasource/nuget', () => {
       httpMock
         .scope('https://myprivatefeed')
         .get('/index.json')
+        .twice()
         .reply(200, JSON.parse(nugetIndexV3));
 
       const res = await getPkgReleases({
@@ -370,6 +373,7 @@ describe('datasource/nuget', () => {
       httpMock
         .scope('https://api.nuget.org')
         .get('/v3/index.json')
+        .twice()
         .reply(200, JSON.parse(nugetIndexV3))
         .get('/v3/registration5-gz-semver2/nunit/index.json')
         .reply(200, pkgListV3Registration)
@@ -387,6 +391,7 @@ describe('datasource/nuget', () => {
       const scope = httpMock
         .scope('https://api.nuget.org')
         .get('/v3/index.json')
+        .twice()
         .reply(200, JSON.parse(nugetIndexV3));
       nlogMocks.forEach(({ url, result }) => {
         scope.get(url).reply(200, result);
@@ -404,10 +409,21 @@ describe('datasource/nuget', () => {
       httpMock
         .scope('https://api.nuget.org')
         .get('/v3/registration5-gz-semver2/nunit/index.json')
-        .reply(200, pkgListV3Registration);
+        .reply(
+          200,
+          pkgListV3Registration
+            .replace(/"http:\/\/nunit\.org"/g, '""')
+            .replace('"published": "2012-10-23T15:37:48+00:00",', '')
+        )
+        .get('/v3-flatcontainer/nunit/3.12.0/nunit.nuspec')
+        .reply(
+          200,
+          pkgInfoV3FromNuget.replace('https://github.com/nunit/nunit', '')
+        );
       httpMock
         .scope('https://myprivatefeed')
         .get('/index.json')
+        .twice()
         .reply(200, JSON.parse(nugetIndexV3));
 
       const res = await getPkgReleases({
@@ -415,8 +431,8 @@ describe('datasource/nuget', () => {
       });
       expect(res).not.toBeNull();
       expect(res).toMatchSnapshot();
-      expect(res.sourceUrl).toBeDefined();
       expect(httpMock.getTrace()).toMatchSnapshot();
+      expect(res.sourceUrl).toBeDefined();
     });
     it('processes real data (v2)', async () => {
       httpMock
diff --git a/lib/datasource/nuget/v3.ts b/lib/datasource/nuget/v3.ts
index 4638dba80637d2bb0d961b73c32719501f94dd00..4d0452bffe08e34d0bbf73c8b6aa160adc35911b 100644
--- a/lib/datasource/nuget/v3.ts
+++ b/lib/datasource/nuget/v3.ts
@@ -1,9 +1,12 @@
+import is from '@sindresorhus/is';
+import { RequestError } from 'got';
 import pAll from 'p-all';
 import * as semver from 'semver';
 import { XmlDocument } from 'xmldoc';
 import { logger } from '../../logger';
 import * as packageCache from '../../util/cache/package';
 import { Http } from '../../util/http';
+import { ensureTrailingSlash } from '../../util/url';
 import { Release, ReleaseResult } from '../common';
 
 import { id } from './common';
@@ -47,6 +50,7 @@ export async function getResourceUrl(
       cacheNamespace,
       responseCacheKey
     );
+    // istanbul ignore else: currently not testable
     if (!servicesIndexRaw) {
       servicesIndexRaw = (await http.getJson<ServicesIndexRaw>(url)).body;
       await packageCache.set(
@@ -165,27 +169,44 @@ export async function getReleases(
     releases,
   };
 
-  if (registryUrl.toLowerCase() === defaultNugetFeed.toLowerCase()) {
-    try {
-      const nuspecUrl = `https://api.nuget.org/v3-flatcontainer/${pkgName.toLowerCase()}/${latestStable}/${pkgName.toLowerCase()}.nuspec`;
+  try {
+    const packageBaseAddress = await getResourceUrl(
+      registryUrl,
+      'PackageBaseAddress'
+    );
+    // istanbul ignore else: this is a required v3 api
+    if (is.nonEmptyString(packageBaseAddress)) {
+      const nuspecUrl = `${ensureTrailingSlash(
+        packageBaseAddress
+      )}${pkgName.toLowerCase()}/${latestStable}/${pkgName.toLowerCase()}.nuspec`;
       const metaresult = await http.get(nuspecUrl);
       const nuspec = new XmlDocument(metaresult.body);
       const sourceUrl = nuspec.valueWithPath('metadata.repository@url');
       if (sourceUrl) {
         dep.sourceUrl = sourceUrl;
       }
-    } catch (err) /* istanbul ignore next */ {
+    }
+  } catch (err) /* istanbul ignore next */ {
+    // ignore / silence 404. Seen on proget, if remote connector is used and package is not yet cached
+    if (err instanceof RequestError && err.response?.statusCode === 404) {
       logger.debug(
-        `Cannot obtain sourceUrl for ${pkgName} using version ${latestStable}`
+        { registryUrl, pkgName, pkgVersion: latestStable },
+        `package manifest (.nuspec) not found`
       );
       return dep;
     }
-  } else if (homepage) {
-    dep.sourceUrl = homepage;
+    logger.debug(
+      { err, registryUrl, pkgName, pkgVersion: latestStable },
+      `Cannot obtain sourceUrl`
+    );
+    return dep;
   }
 
+  // istanbul ignore else: not easy testable
   if (homepage) {
-    dep.homepage = homepage;
+    // only assign if not assigned
+    dep.sourceUrl ??= homepage;
+    dep.homepage ??= homepage;
   }
 
   return dep;