6 Causes of Maven "Could not resolve dependencies" Build Failures and How to Fix Them with settings.xml
If a build that worked yesterday suddenly broke
You probably landed here after copying that red console line—Failed to execute goal ... Could not resolve dependencies—straight into a search engine. Short version: that message only reports the result ("couldn't fetch a dependency"). The real cause is hiding a few lines below it.
This happens a lot on locked-down networks with an internal Nexus/Artifactory, a corporate proxy, and a private CA—even when you didn't change a single line of code. This post is Maven-only. We'll pinpoint and recover from the failure in about five minutes using just the mirror/proxy/server tags in settings.xml, the ~/.m2 layout, and a few mvn flags.
Scope: Maven CLI, settings.xml, and the local repository (.m2). We don't cover IDE-embedded builds or other build tools.
Read the error properly first — find the real cause with mvn -X
The most common mistake is staring at the last Failed to execute goal line and giving up. That line always looks the same. What you actually need is the Caused by or Could not transfer artifact line above it.
Turn on debug logging and run it again.
# /save to
mvn -X clean installWith mvn -X, Maven prints which repository it tried, which URL it hit, and why it failed. Which of the keywords below shows up is your branch point.
| Phrase in the log | Mapped cause | One-line meaning |
|---|---|---|
Could not transfer artifact ... Connection refused / timed out | ② Proxy/firewall / ① Wrong mirror URL | Can't reach the repository at all |
PKIX path building failed / unable to find valid certification path | ③ Private-CA SSL failure | TLS handshake rejected |
Could not find artifact ...:jar:1.2.3 in central (404) | ⑤ Bad version / SNAPSHOT never deployed | Reached the repo, but that version isn't there |
Failed to read artifact descriptor / mention of .lastUpdated | ④ Corrupted local cache | Stuck on a broken cache entry |
Cannot access ... in offline mode | ⑥ Misused -o flag | Offline mode, but a new dependency is required |
If you suspect a conflict, start with the dependency tree.
#
mvn dependency:tree
# ,
mvn dependency:tree -Dverbose -Dincludes=org.springframework:spring-coreCause ① Misconfigured internal Nexus/Artifactory mirror in settings.xml
If you see Connection refused and the URL is your internal Nexus (nexus.company.co.kr) rather than Maven Central, it's almost certainly a mirror misconfiguration in settings.xml. Typical triggers: Nexus is down for maintenance, the URL changed, or credentials expired.
Open ~/.m2/settings.xml and check what <mirrorOf> points at. Mirroring only central vs. mirroring * (everything) behaves completely differently.
<!-- ~/.m2/settings.xml : Nexus + -->
<settings>
<servers>
<!-- mirror id when -->
<server>
<id>company-nexus</id>
<username>${env.NEXUS_USER}</username> <!-- -->
<password>${env.NEXUS_PASS}</password>
</server>
</servers>
<mirrors>
<mirror>
<id>company-nexus</id> <!-- server id -->
<name>Company Nexus</name>
<url>https://nexus.example.co.kr/repository/maven-public/</url>
<mirrorOf>*</mirrorOf> <!-- save Request Nexus -->
</mirror>
</mirrors>
</settings>The key point: the <server> id and the <mirror> id must match exactly, or the auth header never gets attached. If you get 401/403, suspect an id mismatch or an expired password first.
Cause ② Corporate proxy/firewall blocking Maven Central
If <mirrorOf> is only central, so Maven has to go out to Maven Central directly, and you get Connection timed out, the corporate firewall is likely blocking you because you didn't go through the proxy. Diagnose the block first.
# when without check (timeout )
curl -I https://repo.maven.apache.org/maven2/
# when check
curl -I -x http://proxy.example.co.kr:8080 https://repo.maven.apache.org/maven2/If you get a 200 through the proxy, register the proxy in settings.xml.
<!-- ~/.m2/settings.xml : when settings -->
<settings>
<proxies>
<proxy>
<id>company-proxy</id>
<active>true</active> <!-- false when, -->
<protocol>http</protocol>
<host>proxy.example.co.kr</host>
<port>8080</port>
<username>proxyUser</username> <!-- when when -->
<password>proxyPass</password>
<!-- Nexus when -->
<nonProxyHosts>nexus.example.co.kr|localhost|127.0.0.1</nonProxyHosts>
</proxy>
</proxies>
</settings>If you omit <nonProxyHosts>, Maven will try to send even internal Nexus traffic through the external proxy and fail again. Also note that Maven Central blocks HTTP and allows HTTPS only, so any leftover http://...central URLs in old configs need to be changed to https://.
Cause ③ PKIX/SSL handshake failure from a private CA
If you see PKIX path building failed or unable to find valid certification path to requested target, it's an SSL trust problem. The internal proxy/Nexus presents a cert signed by a private CA that isn't in the JDK trust store (cacerts), so the handshake is rejected. This is the fastest-growing case as more teams adopt zero-trust and air-gapped networks.
The core fix is importing the private CA certificate into the JDK.
# CA certificate JDK save
keytool -import -trustcacerts -alias company-ca \
-file company-ca.crt \
-keystore "$JAVA_HOME/lib/security/cacerts" \
-storepass changeitCertificate extraction for PKIX errors, chain assembly, and JDK-version-specific paths are covered in a separate PKIX troubleshooting post. Here we only hit the essentials.
Cause ④ Corrupted local repository cache (~/.m2/repository)
If you can reach the repository fine but one specific library keeps failing and the log mentions .lastUpdated, a download was interrupted and the cache is corrupted. Maven leaves a failure marker (*.lastUpdated) and won't retry for a while.
Before wiping all of .m2, clear just the failure markers—it's much faster.
# 1) failed
find ~/.m2 -name "*.lastUpdated" -delete
# 2) after
mvn dependency:purge-local-repository -Dinclude=org.springframework:spring-core
# 3) when
mvn -U clean installA full rm -rf ~/.m2/repository is a last resort. You'll re-download several GB, which is especially wasteful in CI.
Cause ⑤ Version conflict, nonexistent version, or undeployed SNAPSHOT
If you clearly see a 404 like Could not find artifact ...:jar:1.2.3 in central (404), this is not a connectivity problem. You reached the repository; that coordinate (groupId:artifactId:version) simply doesn't exist. The three usual causes:
- A typo or a version that doesn't exist (e.g. a nonexistent
1.2.3) - A colleague ran
mvn installlocally but neverdeployed the SNAPSHOT to Nexus - A version conflict from a transitive dependency pulled in by another library
#
mvn dependency:tree -Dverbose -Dincludes=com.example:problem-libDistinguishing Connection refused (②) from 404 (⑤) is the key. The former means "couldn't open the door"; the latter means "the door opened, but the item isn't there."
Cause ⑥ Misused -U / -o flags
Finally, flags trip people up more often than you'd think.
-o(offline): Offline mode. Maven can't fetch new dependencies; if they aren't in the cache you getCannot access ... in offline mode. Don't leave it on out of habit.-U(update): Forces SNAPSHOTs to be re-fetched. Useful in CI when you need the latest SNAPSHOT, but turning it on for every build adds unnecessary network calls and intermittent failures.
# SNAPSHOT when
mvn -U clean install5-minute diagnostic flowchart
Walk the error text down this list in order and you'll land on your case.
- Does the log contain
PKIXorvalid certification path? → Yes: cause ③ (import the certificate) - Is there a
404orCould not find artifact? → Yes: cause ⑤ (check version / SNAPSHOT) Connection refused / timed outand the failing URL is internal Nexus? → Yes: cause ① (check mirror and auth)Connection timed outand the URL is Maven Central? → Yes: cause ② (configure the proxy)- Is
.lastUpdatedmentioned, or do only one or two artifacts fail? → Yes: cause ④ (find ~/.m2 -name "*.lastUpdated" -delete) - Is there an
offline modemessage? → Yes: cause ⑥ (remove-o)
If these six steps don't catch it, temporarily disable settings.xml and run once in a vanilla environment to isolate environment variables.
What I've learned in practice
In my experience, 80% of "new hire's laptop won't build" failures on air-gapped projects were causes ① and ③. Once teams started shipping a known-good settings.xml plus the internal CA cert via an onboarding script, the "the build doesn't work" tickets almost disappeared. Version-controlling a standard settings.xml is far cheaper than having every individual debug it.
Recurrence-prevention checklist
- Version-control a team-standard
settings.xml; keep passwords in environment variables - Cache
~/.m2/repositoryin CI (GitHub Actions/Jenkins), but exclude*.lastUpdatedfrom the cache key - Use
-Uonly on jobs that must refresh SNAPSHOTs; leave it off for regular builds - Standardize every repository URL on
https://(Maven Central no longer allows HTTP) - Bake the internal CA certificate into the JDK image / onboarding script
FAQ
Q. Are Could not resolve dependencies and Failed to execute goal different errors?
A. They're effectively one package. Failed to execute goal is the outer message that a plugin stopped; Could not resolve dependencies is the direct cause. Always look one level down at the Caused by or Could not transfer artifact line for the real reason.
Q. Is it okay to delete all of ~/.m2/repository?
A. Yes, but it's a last resort. First delete only the failure markers with find ~/.m2 -name "*.lastUpdated" -delete, or purge just the bad dependency with mvn dependency:purge-local-repository. A full wipe forces a multi-GB re-download and is especially inefficient in CI.
Q. How do I tell a 404 from Connection refused? A. A 404 means "reached the repository, but that version isn't there" (cause ⑤). Connection refused/timed out means "couldn't reach the repository at all" (causes ① and ②). For 404, check the version and whether the SNAPSHOT was deployed; for refused, check the mirror URL and proxy settings.
Sources and checks vary by article. Only articles with a recorded check date, scope and sources below were checked, and only within that scope. For other articles, verify against the current docs for your version before applying anything, and email us about errors. Editorial policy · email us
This article has no recorded human check (date and scope) yet.
Comments
Be the first to comment.