# How to Fix Go Dependency Version Conflict
Dependency version conflicts occur when different modules require incompatible versions of the same dependency. Go's minimal version selection helps manage this.
Error Patterns
Version Mismatch
```text go: github.com/pkg/a requires github.com/pkg/c@v1.0.0 go: github.com/pkg/b requires github.com/pkg/c@v1.2.0 go: version conflict: github.com/pkg/c@v1.0.0 vs v1.2.0
go: module github.com/pkg/c@v1.5.0: revision v1.5.0 does not exist ```
Build Error from Conflict
build constraint cannot be satisfied
cannot load package: import cycle
undefined: someFunction (version mismatch)Common Causes
- 1.Transitive dependency conflict - Different modules require different versions
- 2.Version not existing - Required version tag doesn't exist
- 3.Breaking changes - API changed between versions
- 4.Missing indirect declaration - Indirect dependency not in go.mod
- 5.Outdated go.mod - Dependencies not updated
Diagnosis Steps
Step 1: Check Module Graph
go mod graph
# Shows all dependencies and their versionsStep 2: List Dependencies
go list -m all
# Lists all modules with versionsStep 3: Check Why a Dependency is Needed
go mod why github.com/pkg/c
# Shows import chain that requires this dependencyStep 4: Verify go.mod Contents
cat go.modSolutions
Solution 1: Run go mod tidy
```bash # Update go.mod with minimal needed versions go mod tidy
# This resolves most conflicts automatically # Uses minimal version selection principle ```
Solution 2: Update Specific Dependency
```bash # Update to latest version go get github.com/pkg/c@latest
# Update to specific version go get github.com/pkg/c@v1.2.0
# Update all dependencies go get -u ./...
# Update only direct dependencies go get -u=direct ./... ```
Solution 3: Use Replace Directive
```go // go.mod module myproject
go 1.21
require ( github.com/pkg/a v1.0.0 github.com/pkg/b v1.0.0 )
// Replace conflicting dependency with compatible version replace github.com/pkg/c => github.com/pkg/c v1.2.0
// Or replace with local version for development replace github.com/pkg/c => ../local-c
// Or replace with fork replace github.com/pkg/c => github.com/myfork/c v0.0.0-20240101-abcd123 ```
Solution 4: Add Indirect Dependencies
```bash # If go.mod is missing indirect dependency go mod tidy // Adds indirect dependencies
# Manual addition (if needed) go get github.com/pkg/c@v1.2.0 ```
// go.mod with indirect dependency
require (
github.com/pkg/a v1.0.0
github.com/pkg/b v1.0.0
github.com/pkg/c v1.2.0 // indirect
)Solution 5: Upgrade All Dependencies
```bash # Create backup cp go.mod go.mod.bak cp go.sum go.sum.bak
# Upgrade all go get -u -t ./... go mod tidy
# Test after upgrade go test ./... ```
Solution 6: Use go.work for Multi-Module
```bash # Create workspace for multiple modules go work init ./module1 ./module2
# This creates go.work file ```
```go // go.work go 1.21
use ( ./module1 ./module2 )
replace github.com/pkg/c => ./local-c ```
Solution 7: Use Vendor Mode
```bash # Vendor all dependencies go mod vendor
# Build from vendor (ensures consistent versions) go build -mod=vendor
# This guarantees same versions across builds ```
Solution 8: Fix Pre-release Version Issues
```bash # For pre-release versions (v0.x.x or with prerelease tags) go get github.com/pkg/c@v0.0.0-20231201-abcd1234
# Or use latest commit go get github.com/pkg/c@main ```
Minimal Version Selection
Go uses minimal version selection (MVS):
- Selects the minimum version that satisfies all requirements
- Not highest version like npm/Maven
- More predictable and reproducible
```go // If A requires C@v1.0.0 and B requires C@v1.2.0 // Go selects v1.2.0 (minimum that satisfies both)
// If you want higher version, must explicitly require require github.com/pkg/c v1.5.0 ```
Common Scenarios
Scenario 1: Major Version Conflict
```go // Different major versions are treated as different modules // github.com/pkg/c v1 and v2 are separate modules
require ( github.com/pkg/c v1.2.0 // Major version 1 github.com/pkg/c/v2 v2.0.0 // Major version 2 (different path) ) ```
Scenario 2: Breaking API Change
```go // pkg/c changed API between v1.0.0 and v1.2.0
// Option 1: Update your code to use new API // Option 2: Use replace to stay on old version replace github.com/pkg/c => github.com/pkg/c v1.0.0
// Option 3: Fork and fix replace github.com/pkg/c => github.com/myfork/c v0.0.0-custom ```
Scenario 3: Private Repository
```bash # Configure GOPRIVATE go env -w GOPRIVATE=github.com/mycompany/*
# This skips checksum verification for private repos ```
Scenario 4: Cleaning Up
```bash # Remove unused dependencies go mod tidy -v
# Verify all dependencies go mod verify
# Check for updates go list -u -m all ```
Dependency Management Best Practices
Regular Updates
# Weekly/monthly routine
go get -u ./...
go mod tidy
go test ./...Pin Versions for Stability
```go // For production, pin specific versions require ( github.com/pkg/a v1.2.3 github.com/pkg/b v2.0.1 )
// Avoid using @latest in go.mod ```
Document Why Replace Is Used
// go.mod - add comments
replace github.com/pkg/c => github.com/pkg/c v1.0.0
// ^ Required because pkg/b doesn't support c v1.2.0 yet
// TODO: Remove when pkg/b is updatedDebug Commands
```bash # Show module dependency graph go mod graph | grep "github.com/pkg/c"
# Show why dependency is needed go mod why -m github.com/pkg/c
# List modules with updates available go list -u -m all
# Show detailed module info go list -m -json github.com/pkg/c
# Download specific module go mod download github.com/pkg/c@v1.2.0 ```
Prevention Tips
- 1.Run go mod tidy regularly - After adding imports, before commits
- 2.Pin versions in go.mod - Avoid @latest for production
- 3.Use replace sparingly - Only for temporary fixes
- 4.Document replace directives - Explain why and add TODO
- 5.Test after dependency changes - Run tests before committing
Related Errors
module not found- Dependency doesn't existrevision does not exist- Tag or commit not foundchecksum mismatch- go.sum needs update