Skip to content
Latchkey

Maven "Could not transfer artifact ... 401/403" - Fix Repo Auth

Maven reached the private repository but was refused with a 401 (not authenticated) or 403 (authenticated, not allowed). The credentials in settings.xml are missing, wrong, or do not match the repository id.

What this error means

Resolution against a private Nexus/Artifactory fails with Could not transfer artifact ... authentication failed ... status code: 401 or 403. Public Central artifacts download fine; only the authenticated repo fails.

mvn output
[ERROR] Failed to execute goal on project app: Could not transfer artifact
com.example:lib:jar:1.4.0 from/to internal (https://nexus.example.com/repo):
authentication failed for https://nexus.example.com/repo/.../lib-1.4.0.jar,
status: 401 Unauthorized

Common causes

Repository id does not match a <server> id

Maven binds credentials to a repo by id. If the <repository><id> in the POM is not exactly equal to a <server><id> in settings.xml, no auth is sent and the repo answers 401.

Token missing, stale, or wrong scope

The CI secret feeding settings.xml may be empty, expired, or scoped read-only when a write is attempted (403). An unauthenticated request is also a 401.

How to fix it

Write a settings.xml from CI secrets and pass it explicitly

Generate the file in the job from secrets, with the server id matching the repository id, and point Maven at it.

Terminal
cat > ./.ci/settings.xml <<'XML'
<settings>
  <servers>
    <server>
      <id>internal</id>
      <username>${env.MVN_USER}</username>
      <password>${env.MVN_TOKEN}</password>
    </server>
  </servers>
</settings>
XML
mvn -B -s ./.ci/settings.xml verify

Match ids and verify the token scope

  1. Confirm the repository <id> in the POM equals the <server><id> in settings.xml, character for character.
  2. For a 403 on deploy, use a write-scoped token; a read token resolves but cannot publish.
  3. Run mvn -X to see which server entry Maven selected for the failing host.

How to prevent it

  • Keep repository and server ids identical, inject tokens from CI secrets at build time, and scope read vs write tokens separately.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →