Skip to content
Latchkey

Gradle "Could not GET ... 401" From Private Repo - Fix Auth in CI

Gradle made an authenticated request to a private repository and got a 401. The credentials {} block is missing, or the username/token it reads from the environment is empty in CI.

What this error means

Resolution of a private artifact fails with Could not GET 'https://nexus.example.com/...' received status code 401 from server: Unauthorized. Public artifacts resolve; only the authenticated repo fails.

gradle output
> Could not resolve com.example:lib:2.3.1.
   > Could not get resource 'https://nexus.example.com/.../lib-2.3.1.pom'.
      > Could not GET 'https://nexus.example.com/.../lib-2.3.1.pom'.
         Received status code 401 from server: Unauthorized

Common causes

No credentials block on the repository

A maven { url = ... } without a credentials {} sends no auth, so the private repo answers 401.

Credential env vars empty in CI

The credentials block reads MVN_USER/MVN_TOKEN, but the CI job did not inject those secrets, so Gradle sends blank credentials.

How to fix it

Add a credentials block reading CI secrets

Wire the username and token from environment variables Gradle reads at configuration time.

build.gradle.kts
repositories {
    maven {
        url = uri("https://nexus.example.com/repository/maven-releases/")
        credentials {
            username = providers.environmentVariable("MVN_USER").orNull
            password = providers.environmentVariable("MVN_TOKEN").orNull
        }
    }
}

Inject the secrets into the job

Provide the env vars from CI secrets so the credentials block is populated.

.github/workflows/ci.yml
- env:
    MVN_USER: ${{ secrets.MVN_USER }}
    MVN_TOKEN: ${{ secrets.MVN_TOKEN }}
  run: ./gradlew build

How to prevent it

  • Declare credentials {} on every private repository and source the values from CI secrets, never committed gradle.properties.

Related guides

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