Repository: dependency-check/DependencyCheck (language: java)

Issue:
Server status: 403 - Server reason: Forbidden
Hello, 
Since yesterday we keep getting this error. I tried upgrading from 12.0.1 to 12.1.0 but the error is the same.:

```
Could not connect to Central search. Analysis failed.
java.io.IOException: Finally failed connecting to Central search. Giving up after 7 tries.
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.fetchMavenArtifacts(CentralAnalyzer.java:362)
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.analyzeDependency(CentralAnalyzer.java:228)
	at org.owasp.dependencycheck.analyzer.AbstractAnalyzer.analyze(AbstractAnalyzer.java:131)
	at org.owasp.dependencycheck.AnalysisTask.call(AnalysisTask.java:88)
	at org.owasp.dependencycheck.AnalysisTask.call(AnalysisTask.java:37)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.io.IOException: https://search.maven.org/solrsearch/select?q=1:afb50d08a724ea8f635f8ebd0c0d17d1db279fb5&wt=xml - Server status: 403 - Server reason: Forbidden
	at org.owasp.dependencycheck.utils.Downloader.fetchAndHandle(Downloader.java:724)
	at org.owasp.dependencycheck.utils.Downloader.fetchAndHandle(Downloader.java:685)
	at org.owasp.dependencycheck.data.central.CentralSearch.searchSha1(CentralSearch.java:162)
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.fetchMavenArtifacts(CentralAnalyzer.java:339)
	... 8 more
An error occurred while analyzing '/root/.gradle/caches/modules-2/files-2.1/net.sf.saxon/Saxon-HE/12.2/afb50d08a724ea8f635f8ebd0c0d17d1db279fb5/Saxon-HE-12.2.jar' (Central Analyzer).
Could not connect to Central search. Analysis failed.
java.io.IOException: Finally failed connecting to Central search. Giving up after 7 tries.
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.fetchMavenArtifacts(CentralAnalyzer.java:362)
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.analyzeDependency(CentralAnalyzer.java:228)
	at org.owasp.dependencycheck.analyzer.AbstractAnalyzer.analyze(AbstractAnalyzer.java:131)
	at org.owasp.dependencycheck.AnalysisTask.call(AnalysisTask.java:88)
	at org.owasp.dependencycheck.AnalysisTask.call(AnalysisTask.java:37)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.io.IOException: https://search.maven.org/solrsearch/select?q=1:331f93a364f95a05888419b4e138d27cd774206a&wt=xml - Server status: 403 - Server reason: Forbidden
	at org.owasp.dependencycheck.utils.Downloader.fetchAndHandle(Downloader.java:724)
	at org.owasp.dependencycheck.utils.Downloader.fetchAndHandle(Downloader.java:685)
	at org.owasp.dependencycheck.data.central.CentralSearch.searchSha1(CentralSearch.java:162)
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.fetchMavenArtifacts(CentralAnalyzer.java:339)
	... 8 more
An error occurred while analyzing '/root/.gradle/caches/modules-2/files-2.1/org.checkerframework/checker-qual/3.27.0/331f93a364f95a05888419b4e138d27cd774206a/checker-qual-3.27.0.jar' (Central Analyzer).
Could not connect to Central search. Analysis failed.
java.io.IOException: Finally failed connecting to Central search. Giving up after 7 tries.
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.fetchMavenArtifacts(CentralAnalyzer.java:362)
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.analyzeDependency(CentralAnalyzer.java:228)
	at org.owasp.dependencycheck.analyzer.AbstractAnalyzer.analyze(AbstractAnalyzer.java:131)
	at org.owasp.dependencycheck.AnalysisTask.call(AnalysisTask.java:88)
	at org.owasp.dependencycheck.AnalysisTask.call(AnalysisTask.java:37)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.io.IOException: https://search.maven.org/solrsearch/select?q=1:741567fd1d5bdd67c385d48b1a8f6576d4ae904e&wt=xml - Server status: 403 - Server reason: Forbidden
	at org.owasp.dependencycheck.utils.Downloader.fetchAndHandle(Downloader.java:724)
	at org.owasp.dependencycheck.utils.Downloader.fetchAndHandle(Downloader.java:685)
	at org.owasp.dependencycheck.data.central.CentralSearch.searchSha1(CentralSearch.java:162)
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.fetchMavenArtifacts(CentralAnalyzer.java:339)
	... 8 more
An error occurred while analyzing '/root/.gradle/caches/modules-2/files-2.1/org.xmlresolver/xmlresolver/5.1.2/741567fd1d5bdd67c385d48b1a8f6576d4ae904e/xmlresolver-5.1.2.jar' (Central Analyzer).
Could not connect to Central search. Analysis failed.
java.io.IOException: Finally failed connecting to Central search. Giving up after 7 tries.
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.fetchMavenArtifacts(CentralAnalyzer.java:362)
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.analyzeDependency(CentralAnalyzer.java:228)
	at org.owasp.dependencycheck.analyzer.AbstractAnalyzer.analyze(AbstractAnalyzer.java:131)
	at org.owasp.dependencycheck.AnalysisTask.call(AnalysisTask.java:88)
	at org.owasp.dependencycheck.AnalysisTask.call(AnalysisTask.java:37)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.io.IOException: https://search.maven.org/solrsearch/select?q=1:00ffd63c9ca11ce986d2925e1c93de0d06b37cc4&wt=xml - Server status: 403 - Server reason: Forbidden
	at org.owasp.dependencycheck.utils.Downloader.fetchAndHandle(Downloader.java:724)
	at org.owasp.dependencycheck.utils.Downloader.fetchAndHandle(Downloader.java:685)
	at org.owasp.dependencycheck.data.central.CentralSearch.searchSha1(CentralSearch.java:162)
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.fetchMavenArtifacts(CentralAnalyzer.java:339)
	... 8 more
An error occurred while analyzing '/root/.gradle/caches/modules-2/files-2.1/org.xmlresolver/xmlresolver/5.1.2/ffd63c9ca11ce986d2925e1c93de0d06b37cc4/xmlresolver-5.1.2-data.jar' (Central Analyzer).
Could not connect to Central search. Analysis failed.
java.io.IOException: Finally failed connecting to Central search. Giving up after 7 tries.
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.fetchMavenArtifacts(CentralAnalyzer.java:362)
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.analyzeDependency(CentralAnalyzer.java:228)
	at org.owasp.dependencycheck.analyzer.AbstractAnalyzer.analyze(AbstractAnalyzer.java:131)
	at org.owasp.dependencycheck.AnalysisTask.call(AnalysisTask.java:88)
	at org.owasp.dependencycheck.AnalysisTask.call(AnalysisTask.java:37)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.io.IOException: https://search.maven.org/solrsearch/select?q=1:ff7227fc62338e0f6eba3f9f94c12eb952d4da95&wt=xml - Server status: 403 - Server reason: Forbidden
	at org.owasp.dependencycheck.utils.Downloader.fetchAndHandle(Downloader.java:724)
	at org.owasp.dependencycheck.utils.Downloader.fetchAndHandle(Downloader.java:685)
	at org.owasp.dependencycheck.data.central.CentralSearch.searchSha1(CentralSearch.java:162)
	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.fetchMavenArtifacts(CentralAnalyzer.java:339)
	... 8 more
An error occurred while analyzing '/root/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-web/3.4.1/ff7227fc62338e0f6eba3f9f94c12eb952d4da95/spring-boot-starter-web-3.4.1.jar' (Central Analyzer).
Could not connect to Central search. Analysis failed.
java.io.IOException: Finally failed connecting to Central search. Giving up after 7 tries.```


Discussion / hints:
Something somewhere on the network path from your system to Maven Central search is blocking your access (http 403 forbidden). It's logical that an update in this tool wouldn't solve it.
It might be a side-effect of the problems they self-reported on their status site https://status.maven.org/


+1.

I'm also getting a similar issue in CI build and already using the latest dependency plugin version.

`Could not connect to Central search. Analysis failed.

java.io.IOException: Finally failed connecting to Central search. Giving up after 7 tries.

	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.fetchMavenArtifacts(CentralAnalyzer.java:362)

	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.analyzeDependency(CentralAnalyzer.java:228)

	at org.owasp.dependencycheck.analyzer.AbstractAnalyzer.analyze(AbstractAnalyzer.java:131)

	at org.owasp.dependencycheck.AnalysisTask.call(AnalysisTask.java:88)

	at org.owasp.dependencycheck.AnalysisTask.call(AnalysisTask.java:37)

	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)

	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)

	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)

	at java.base/java.lang.Thread.run(Thread.java:840)

Caused by: java.io.IOException: https://search.maven.org/solrsearch/select?q=1:8f8cf0372abf564913e9796623aac4c8ea44025a&wt=xml - Server status: 403 - Server reason: Forbidden

	at org.owasp.dependencycheck.utils.Downloader.fetchAndHandle(Downloader.java:724)

	at org.owasp.dependencycheck.utils.Downloader.fetchAndHandle(Downloader.java:685)

	at org.owasp.dependencycheck.data.central.CentralSearch.searchSha1(CentralSearch.java:162)

	at org.owasp.dependencycheck.analyzer.CentralAnalyzer.fetchMavenArtifacts(CentralAnalyzer.java:339)

	... 8 more

An error occurred while analyzing '/home/ubuntu/.gradle/caches/modules-2/files-2.1/org.projectlombok/lombok/1.18.26/8f8cf0372abf564913e9796623aac4c8ea44025a/lombok-1.18.26.jar' (Central Analyzer).

Could not connect to Central search. Analysis failed.

java.io.IOException: Finally failed connecting to Central search. Giving up after 7 tries.`
The Maven repository was acquired by Sonatype a long time ago. After that, the redirection from https://search.maven.org/ to https://central.sonatype.com/ always worked. Now the old site is unavailable, while the new one is accessible. Is there a possibility to change the link to access the Maven repository?
Hi, I verified the same issue.
Considering the error I've looked into the repository and it seems there is the following configuration info: https://github.com/dependency-check/DependencyCheck/blob/7492649c59ed2d0f4544d44cf58ff17b60bef15d/core/src/main/resources/dependencycheck.properties#L77
In my scenario, I've dependency-check installed with brew. I've found references for this file in the following locations:
- /usr/local/Cellar/dependency-check/12.1.0/libexec/etc/dependencycheck.properties 
- /usr/local/Cellar/dependency-check/12.1.0/.bottle/etc/dependencycheck/dependencycheck.properties

I changed the property to the new: 
`analyzer.central.url=https://central.sonatype.com/solrsearch/select`

This solved the issue. Maybe not the cleanest solution, but this workaround worked for me.
I suppose a fix will come in the next minor upgrade.

Regards,
Massimo.
@max see https://github.com/dependency-check/DependencyCheck/issues/7232#issuecomment-2538658500. You configuration effectively disables the analyzer.

Also see https://github.com/dependency-check/DependencyCheck/issues/5827
Central search status page: https://status.maven.org/
@jeremylong so you suggest that this is solely based on network issues?
I am getting those 403 errors too in URLs that apparently work fine like https://search.maven.org/solrsearch/select?q=g:%22org.springframework.boot%22+AND+a:%22spring-boot%22+AND+v:%223.1.1%22&rows=20&wt=json but dependency-check gets the error. Maven central status page does not show any incident right now...
I just run ODC:

```
[INFO] Analysis Started
[INFO] Finished Archive Analyzer (0 seconds)
[INFO] Finished File Name Analyzer (0 seconds)
[INFO] Finished Jar Analyzer (1 seconds)
[INFO] Finished Central Analyzer (1 seconds)
[INFO] Finished Assembly Analyzer (0 seconds)
...
```

No errors from the central analyzer, and my report contains data from the analyzer.
So I noticed this is tagged as unable to reproduce however, since yesterday our pipelines have ran dependency check analyze job more than 10 times and we never been able to get any error free output. And there are already others who have the same issue with us. 
Disable the central analyzer and/or contact sonatype. I can make requests to the API and everything appears to be working from my end. The API is not owned or operated by the dependency-check team.

A better recommendation would be to use the Maven or Gradle plugins as they can retrieve the information from the build system itself.
Per [documentation](https://jeremylong.github.io/DependencyCheck/dependency-check-gradle/configuration-aggregate.html#:~:text=analyzers-,centralEnabled,-Sets%20whether%20Central) the central analyzer is disabled by default.

But it looks like the Central Analyzer is enabled by default actually - https://github.com/dependency-check/DependencyCheck/blob/7492649c59ed2d0f4544d44cf58ff17b60bef15d/core/src/main/resources/dependencycheck.properties#L138

Which one of these behavior is correct?
documentation always lies. Sorry about that. I forgot that there are some cases where gradle still benefits from the central analyzer.
@mviku documentation will be updated: https://github.com/dependency-check/DependencyCheck/pull/7511
@yansifw The network error is unclear and intermittent. I get a 403 error from my work network, but everything works fine on my home network. I also tried it at work through a proxy, and it worked fine as well. It's completely unclear what the principle of the failures is. Could the networks be blocking due to the frequency of requests? (There are many CI/CD processes running.)
Or it is possible that because you have so many requests the NVD has blocked your IP. I would highly recommend setting up a mirror of the NVD API data: https://github.com/jeremylong/open-vulnerability-cli?tab=readme-ov-file#caching-the-nvd-cve-data

There is even a handy docker image: https://github.com/jeremylong/open-vulnerability-cli?tab=readme-ov-file#docker-image
In my case I have a hosted DB of NVD data and I got only the errors from maven central, they might have some intermittent errors 
Same, we have also mirrored it already. 
@jeremylong  We're not talking about checking vulnerabilities in NVD databases right now, but about the availability of Maven Central. By the way, regarding the mirror — I recently tried to set up a mirror from Dependency-Track, but there was an issue with API version compatibility. Maybe it has been resolved now; I'll try again.
I'm getting this same error after upgrading to 12.1.0. @jeremylong  After changing just my version number in Gradle, this happens. On 7.1.1, I wasn't getting this issue.
> documentation always lies. Sorry about that. I forgot that there are some cases where gradle still benefits from the central analyzer.

@jeremylong  Could you specify or point me to any earlier discussion on why Gradle benefits from central analyzer compared to Maven

I have both Maven and Gradle based builds in my setup. Looking at the difference in behavior - just wanted to understand the reasoning behind it.

As of now thinking to disable central analyzer in Gradle builds, to skip this issue and also to make the behavior in sync with maven builds.
Gradle benefits when a dependent JAR is built with Gradle - because 99/100 times if the JAR was built with gradle it will not contain a copy of the pom.xml in the META-INF/maven directory. Thus, using the central analyzer can benefit gradle scans.
fwiw, we just started getting this same error a few days ago as well, but it seems to have magically resolved itself today
![Image](https://github.com/user-attachments/assets/d10a77b0-4527-4048-89a5-eb6b55572947)
Happening just now... 
@mo7ty no use in posting a 'me too'. Central Search is denying you access for whatever reason they have (most likely cause I can think of would be some IDS/IPS system fronting their service flagging your source IP as an abuse-suspect and therefor responding with access denied).
Was just to inform that it is reproducible.

Either way, similar to the `search.maven.org` down, is there a way to disable this integration in DC? `centralEnabled=false`? 
Yes, if you suffer from the access denied on Maven Central you can disable the Central Analyzer, with the downside of potentially missing out on some maven g/a/v detections that would otherwise yield you a better CPE match.

Also good to check your CI systems that they cache and share the ODC datafolder, because if this is about a 'too many requests' scenario that makes some middleware lock you out you can reduce the amount of calls to MavenCentral without disabling the analyzer as the CentralAnalyzer is keeping a cache of recent sha1-to-maven-artifact resolution results for reuse. That maven cache is stored alongside other caches in the ODC datafolder.
I have not yet experienced even a single 403 from maven search.

See the configuration page of the ODC variant that you use for the exact flags (they can be found on the gitlab pages linked from the main readme)

Fix patch:
diff --git a/core/src/main/java/org/owasp/dependencycheck/analyzer/CentralAnalyzer.java b/core/src/main/java/org/owasp/dependencycheck/analyzer/CentralAnalyzer.java
index 098585c22dd..9349413e34f 100644
--- a/core/src/main/java/org/owasp/dependencycheck/analyzer/CentralAnalyzer.java
+++ b/core/src/main/java/org/owasp/dependencycheck/analyzer/CentralAnalyzer.java
@@ -34,6 +34,7 @@
 import org.owasp.dependencycheck.utils.Downloader;
 import org.owasp.dependencycheck.utils.FileFilterBuilder;
 import org.owasp.dependencycheck.utils.FileUtils;
+import org.owasp.dependencycheck.utils.ForbiddenException;
 import org.owasp.dependencycheck.utils.InvalidSettingException;
 import org.owasp.dependencycheck.utils.ResourceNotFoundException;
 import org.owasp.dependencycheck.utils.Settings;
@@ -309,6 +310,12 @@ public void analyzeDependency(Dependency dependency, Engine engine) throws Analy
             LOGGER.info("invalid sha1-hash on {}", dependency.getFileName());
         } catch (FileNotFoundException fnfe) {
             LOGGER.debug("Artifact not found in repository: '{}", dependency.getFileName());
+        } catch (ForbiddenException e) {
+            final String message = "Connection to Central search refused. This is most likely not a problem with " +
+                    "Dependency-Check itself and is related to network connectivity. Please check " +
+                    "https://central.sonatype.org/faq/403-error-central/.";
+            LOGGER.error(message);
+            throw new AnalysisException(message, e);
         } catch (IOException ioe) {
             final String message = "Could not connect to Central search. Analysis failed.";
             LOGGER.error(message, ioe);
@@ -330,7 +337,8 @@ public void analyzeDependency(Dependency dependency, Engine engine) throws Analy
      * @throws TooManyRequestsException if Central has received too many
      * requests.
      */
-    protected List<MavenArtifact> fetchMavenArtifacts(Dependency dependency) throws IOException, TooManyRequestsException {
+    protected List<MavenArtifact> fetchMavenArtifacts(Dependency dependency) throws IOException,
+            TooManyRequestsException {
         IOException lastException = null;
         long sleepingTimeBetweenRetriesInMillis = BASE_RETRY_WAIT;
         int triesLeft = numberOfRetries;
diff --git a/core/src/main/java/org/owasp/dependencycheck/data/artifactory/ArtifactorySearch.java b/core/src/main/java/org/owasp/dependencycheck/data/artifactory/ArtifactorySearch.java
index 534b5d899eb..8674103c388 100644
--- a/core/src/main/java/org/owasp/dependencycheck/data/artifactory/ArtifactorySearch.java
+++ b/core/src/main/java/org/owasp/dependencycheck/data/artifactory/ArtifactorySearch.java
@@ -33,6 +33,7 @@
 import org.owasp.dependencycheck.dependency.Dependency;
 import org.owasp.dependencycheck.utils.Checksum;
 import org.owasp.dependencycheck.utils.Downloader;
+import org.owasp.dependencycheck.utils.ForbiddenException;
 import org.owasp.dependencycheck.utils.ResourceNotFoundException;
 import org.owasp.dependencycheck.utils.Settings;
 import org.owasp.dependencycheck.utils.TooManyRequestsException;
@@ -44,7 +45,7 @@
  * Class of methods to search Artifactory for hashes and determine Maven GAV
  * from there.
  *
- * Data classes copied from JFrog's artifactory-client-java project.
+ * <p>Data classes copied from JFrog's artifactory-client-java project.</p>
  *
  * @author nhenneaux
  */
@@ -116,6 +117,8 @@ public List<MavenArtifact> search(Dependency dependency) throws IOException {
             throw new IOException(msg.append(" (400): Invalid URL").toString(), e);
         } catch (ResourceNotFoundException e) {
             throw new IOException(msg.append(" (404): Not found").toString(), e);
+        } catch (ForbiddenException e) {
+            throw new IOException(msg.append(" (403): Forbidden").toString(), e);
         }
     }
 
diff --git a/core/src/main/java/org/owasp/dependencycheck/data/central/CentralSearch.java b/core/src/main/java/org/owasp/dependencycheck/data/central/CentralSearch.java
index 0b598684e99..3ee1135a1ec 100644
--- a/core/src/main/java/org/owasp/dependencycheck/data/central/CentralSearch.java
+++ b/core/src/main/java/org/owasp/dependencycheck/data/central/CentralSearch.java
@@ -21,6 +21,7 @@
 import org.apache.hc.core5.http.message.BasicHeader;
 import org.owasp.dependencycheck.utils.DownloadFailedException;
 import org.owasp.dependencycheck.utils.Downloader;
+import org.owasp.dependencycheck.utils.ForbiddenException;
 import org.owasp.dependencycheck.utils.ResourceNotFoundException;
 import org.owasp.dependencycheck.utils.TooManyRequestsException;
 import java.io.FileNotFoundException;
@@ -135,14 +136,14 @@ public CentralSearch(Settings settings) throws MalformedURLException {
      * @throws TooManyRequestsException if Central has received too many
      * requests.
      */
-    public List<MavenArtifact> searchSha1(String sha1) throws IOException, TooManyRequestsException {
+    public List<MavenArtifact> searchSha1(String sha1) throws IOException, TooManyRequestsException, ForbiddenException {
         if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
             throw new IllegalArgumentException("Invalid SHA1 format");
         }
         if (cache != null) {
             final List<MavenArtifact> cached = cache.get(sha1);
             if (cached != null) {
-                LOGGER.debug("cache hit for Central: " + sha1);
+                LOGGER.debug("cache hit for Central: {}", sha1);
                 if (cached.isEmpty()) {
                     throw new FileNotFoundException("Artifact not found in Central");
                 }
@@ -180,6 +181,9 @@ public List<MavenArtifact> searchSha1(String sha1) throws IOException, TooManyRe
         } catch (URISyntaxException e) {
             final String errorMessage = "Could not convert central search URL to a URI " + e.getMessage();
             throw new IOException(errorMessage, e);
+        } catch (ForbiddenException e) {
+            final String errorMessage = "Forbidden access to MavenCentral " + e.getMessage();
+            throw new ForbiddenException(errorMessage, e);
         }
         if (cache != null) {
             cache.put(sha1, result);
diff --git a/core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusV2Search.java b/core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusV2Search.java
index 3c8766fceb9..9e2401fc3e8 100644
--- a/core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusV2Search.java
+++ b/core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusV2Search.java
@@ -34,6 +34,7 @@
 import org.apache.hc.core5.http.message.BasicHeader;
 import org.owasp.dependencycheck.utils.DownloadFailedException;
 import org.owasp.dependencycheck.utils.Downloader;
+import org.owasp.dependencycheck.utils.ForbiddenException;
 import org.owasp.dependencycheck.utils.ResourceNotFoundException;
 import org.owasp.dependencycheck.utils.Settings;
 
@@ -147,7 +148,7 @@ public MavenArtifact searchSha1(String sha1) throws IOException {
                 throw new IOException("Could not connect to Nexus");
         } catch (ResourceNotFoundException e) {
             throw new FileNotFoundException("Artifact not found in Nexus");
-        } catch (XPathExpressionException | URISyntaxException e) {
+        } catch (XPathExpressionException | URISyntaxException | ForbiddenException e) {
             throw new IOException(e.getMessage(), e);
         }
     }
diff --git a/core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusV3Search.java b/core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusV3Search.java
index 943e21f3f84..8bb31bc7573 100644
--- a/core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusV3Search.java
+++ b/core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusV3Search.java
@@ -27,6 +27,7 @@
 import org.jetbrains.annotations.Nullable;
 import org.owasp.dependencycheck.utils.DownloadFailedException;
 import org.owasp.dependencycheck.utils.Downloader;
+import org.owasp.dependencycheck.utils.ForbiddenException;
 import org.owasp.dependencycheck.utils.ResourceNotFoundException;
 import org.owasp.dependencycheck.utils.Settings;
 import org.owasp.dependencycheck.utils.TooManyRequestsException;
@@ -146,7 +147,7 @@ private String retrievePageAndAddMatchingArtifact(CloseableHttpClient client, Li
         try {
             return Downloader.getInstance().fetchAndHandle(client, url, handler, List.of(new BasicHeader(HttpHeaders.ACCEPT,
                             ContentType.APPLICATION_JSON)));
-        } catch (TooManyRequestsException | ResourceNotFoundException | DownloadFailedException e) {
+        } catch (TooManyRequestsException | ResourceNotFoundException | DownloadFailedException | ForbiddenException e) {
             if (LOGGER.isDebugEnabled()) {
                 int responseCode = -1;
                 String responseMessage = "";
diff --git a/utils/src/main/java/org/owasp/dependencycheck/utils/Downloader.java b/utils/src/main/java/org/owasp/dependencycheck/utils/Downloader.java
index e4eb9b69efa..df2ec1f746d 100644
--- a/utils/src/main/java/org/owasp/dependencycheck/utils/Downloader.java
+++ b/utils/src/main/java/org/owasp/dependencycheck/utils/Downloader.java
@@ -649,7 +649,7 @@ public CloseableHttpClient getHttpClient(boolean useProxy) {
      * @throws ResourceNotFoundException When HTTP status 404 is encountered
      */
     public <T> T fetchAndHandle(@NotNull URL url, @NotNull HttpClientResponseHandler<T> handler)
-            throws IOException, TooManyRequestsException, ResourceNotFoundException, URISyntaxException {
+            throws IOException, TooManyRequestsException, ResourceNotFoundException, URISyntaxException, ForbiddenException {
         return fetchAndHandle(url, handler, Collections.emptyList(), true);
     }
 
@@ -666,7 +666,7 @@ public <T> T fetchAndHandle(@NotNull URL url, @NotNull HttpClientResponseHandler
      * @throws ResourceNotFoundException When HTTP status 404 is encountered
      */
     public <T> T fetchAndHandle(@NotNull URL url, @NotNull HttpClientResponseHandler<T> handler, @NotNull List<Header> hdr)
-            throws IOException, TooManyRequestsException, ResourceNotFoundException, URISyntaxException {
+            throws IOException, TooManyRequestsException, ResourceNotFoundException, URISyntaxException, ForbiddenException {
         return fetchAndHandle(url, handler, hdr, true);
     }
 
@@ -684,7 +684,7 @@ public <T> T fetchAndHandle(@NotNull URL url, @NotNull HttpClientResponseHandler
      * @throws ResourceNotFoundException When HTTP status 404 is encountered
      */
     public <T> T fetchAndHandle(@NotNull URL url, @NotNull HttpClientResponseHandler<T> handler, @NotNull List<Header> hdr, boolean useProxy)
-            throws IOException, TooManyRequestsException, ResourceNotFoundException, URISyntaxException {
+            throws IOException, TooManyRequestsException, ResourceNotFoundException, URISyntaxException, ForbiddenException {
         final T data;
         if ("file".equals(url.getProtocol())) {
             final Path p = Paths.get(url.toURI());
@@ -717,7 +717,8 @@ public <T> T fetchAndHandle(@NotNull URL url, @NotNull HttpClientResponseHandler
      * @throws ResourceNotFoundException When HTTP status 404 is encountered
      */
     public <T> T fetchAndHandle(@NotNull CloseableHttpClient client, @NotNull URL url, @NotNull HttpClientResponseHandler<T> handler,
-                                @NotNull List<Header> hdr) throws IOException, TooManyRequestsException, ResourceNotFoundException {
+                                @NotNull List<Header> hdr) throws IOException, TooManyRequestsException,
+            ResourceNotFoundException, ForbiddenException {
         try {
             final String theProtocol = url.getProtocol();
             if (!("http".equals(theProtocol) || "https".equals(theProtocol))) {
@@ -732,6 +733,9 @@ public <T> T fetchAndHandle(@NotNull CloseableHttpClient client, @NotNull URL ur
         } catch (HttpResponseException hre) {
             final String messageFormat = "%s - Server status: %d - Server reason: %s";
             switch (hre.getStatusCode()) {
+                case 403:
+                    throw new ForbiddenException(String.format(messageFormat, url, hre.getStatusCode(),
+                            hre.getReasonPhrase()));
                 case 404:
                     throw new ResourceNotFoundException(String.format(messageFormat, url, hre.getStatusCode(), hre.getReasonPhrase()));
                 case 429:
diff --git a/utils/src/main/java/org/owasp/dependencycheck/utils/ForbiddenException.java b/utils/src/main/java/org/owasp/dependencycheck/utils/ForbiddenException.java
new file mode 100644
index 00000000000..498f24653e4
--- /dev/null
+++ b/utils/src/main/java/org/owasp/dependencycheck/utils/ForbiddenException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.owasp.dependencycheck.utils;
+
+import java.io.IOException;
+
+public class ForbiddenException extends IOException {
+
+    public ForbiddenException(String message) {
+        super(message);
+    }
+
+    public ForbiddenException(String message, ForbiddenException cause) {
+        super(message, cause);
+    }
+}


Test patch:
diff --git a/core/src/test/java/org/owasp/dependencycheck/analyzer/CentralAnalyzerTest.java b/core/src/test/java/org/owasp/dependencycheck/analyzer/CentralAnalyzerTest.java
index fb17c03ea2f..c3496c6b84d 100644
--- a/core/src/test/java/org/owasp/dependencycheck/analyzer/CentralAnalyzerTest.java
+++ b/core/src/test/java/org/owasp/dependencycheck/analyzer/CentralAnalyzerTest.java
@@ -21,6 +21,7 @@
 import org.junit.Test;
 import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
 import org.owasp.dependencycheck.data.central.CentralSearch;
+import org.owasp.dependencycheck.utils.ForbiddenException;
 import org.owasp.dependencycheck.utils.TooManyRequestsException;
 import org.owasp.dependencycheck.data.nexus.MavenArtifact;
 import org.owasp.dependencycheck.dependency.Dependency;
@@ -50,7 +51,7 @@ public class CentralAnalyzerTest extends BaseTest {
 
     @Test
     @SuppressWarnings("PMD.NonStaticInitializer")
-    public void testFetchMavenArtifactsWithoutException() throws IOException, TooManyRequestsException {
+    public void testFetchMavenArtifactsWithoutException() throws IOException, TooManyRequestsException, ForbiddenException {
             CentralAnalyzer instance = new CentralAnalyzer();
             instance.setCentralSearch(centralSearch);
             when(dependency.getSha1sum()).thenReturn(SHA1_SUM);
@@ -64,7 +65,7 @@ public void testFetchMavenArtifactsWithoutException() throws IOException, TooMan
     @Test(expected = FileNotFoundException.class)
     @SuppressWarnings("PMD.NonStaticInitializer")
     public void testFetchMavenArtifactsRethrowsFileNotFoundException()
-            throws IOException, TooManyRequestsException {
+            throws IOException, TooManyRequestsException, ForbiddenException {
         CentralAnalyzer instance = new CentralAnalyzer();
         instance.setCentralSearch(centralSearch);
         when(dependency.getSha1sum()).thenReturn(SHA1_SUM);
@@ -75,7 +76,7 @@ public void testFetchMavenArtifactsRethrowsFileNotFoundException()
     @Test(expected = IOException.class)
     @SuppressWarnings("PMD.NonStaticInitializer")
     public void testFetchMavenArtifactsAlwaysThrowsIOException()
-            throws IOException, TooManyRequestsException {
+            throws IOException, TooManyRequestsException, ForbiddenException {
         getSettings().setInt(Settings.KEYS.ANALYZER_CENTRAL_RETRY_COUNT, 1);
         getSettings().setBoolean(Settings.KEYS.ANALYZER_CENTRAL_USE_CACHE, false);
         CentralAnalyzer instance = new CentralAnalyzer();