Skip to content

Repository Configuration in Gradle: Settings vs Project Repositories

Problem Statement

When trying to add JitPack or other Maven repositories to an Android or Gradle project, developers often encounter the error:

Caused by: org.gradle.api.InvalidUserCodeException: Build was configured to prefer settings repositories over project repositories but repository 'maven' was added by build file 'build.gradle'

This error occurs because newer versions of Gradle (6.8+) introduced a centralized repository declaration system that prioritizes settings-level repositories over project-level repositories.

Root Cause

Gradle 6.8 introduced central declaration of repositories, which provides better performance and consistency across multi-module projects. When your settings.gradle file contains a dependencyResolutionManagement block, Gradle expects all repository declarations to be centralized there rather than in individual build.gradle files.

Solutions

The modern approach is to declare all repositories in your settings.gradle file:

groovy
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}
Full settings.gradle example
groovy
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
        // Add other repositories here
    }
}
rootProject.name = "YourAppName"
include ':app'

Option 2: Adjust Repository Resolution Mode

If you need to maintain some repository declarations in your build files, change the repositories mode:

groovy
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

This mode allows project-level repositories but gives preference to settings-level declarations.

Option 3: Remove Centralized Configuration (Legacy Approach)

If you prefer the traditional approach, remove the dependencyResolutionManagement block from settings.gradle entirely and use project-level repository declarations:

groovy
// In your root build.gradle
allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

WARNING

This approach is not recommended for new projects as the centralized repository management offers better performance and consistency.

Handling Authenticated Repositories

For repositories requiring authentication (like GitHub Packages), use this pattern:

groovy
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven {
            name = "GitHubPackages"
            url = uri("https://maven.pkg.github.com/OWNER/REPOSITORY")
            credentials {
                username = project.findProperty("githubUsername") ?: ""
                password = project.findProperty("githubToken") ?: ""
            }
        }
    }
}

Best Practices

  1. Use centralized repository declarations for better performance and maintainability
  2. Keep repository list minimal to reduce dependency resolution time
  3. Use credentials properties for authenticated repositories rather than hardcoding secrets
  4. Remove deprecated repositories like jcenter() which is being sunset

Common Issues and Fixes

  • Sync fails after changes: Click "Sync Now" in Android Studio or run ./gradlew --refresh-dependencies
  • Duplicate repository errors: Ensure you're not declaring the same repository in both settings.gradle and build.gradle
  • Authentication issues: Verify credentials and network access for private repositories

By following these patterns, you can efficiently manage dependencies while avoiding the "prefer settings repositories" error that occurs when mixing old and new repository declaration approaches.