What's Actually Happening

Go module dependencies have version conflicts. Different modules require incompatible versions of the same dependency.

The Error You'll See

```bash $ go build

go: github.com/example/pkg@v1.2.0 requires github.com/other/lib@v1.0.0: missing go.sum entry ```

Version mismatch:

bash
go: inconsistent vendoring:
    github.com/dep/lib: version varies (v1.0.0 vs v1.1.0)

Minimal version selection error:

bash
go: github.com/project/pkg imports
    github.com/dep/lib: ambiguous import: found github.com/dep/lib in multiple modules

Update conflict:

```bash $ go get github.com/example/pkg@latest

go: github.com/example/pkg@v2.0.0 requires github.com/dep/lib@v2.0.0: already have github.com/dep/lib@v1.0.0 ```

Why This Happens

  1. 1.Version requirements conflict - Dependencies require different versions
  2. 2.Major version mismatch - Different major versions imported
  3. 3.Indirect dependency conflict - Transitive dependency version issue
  4. 4.Missing go.sum entry - Module not in go.sum
  5. 5.Vendoring inconsistency - Vendor directory out of sync
  6. 6.Replace directive missing - Local replacement not configured

Step 1: Analyze Dependency Graph

```bash # View dependency graph: go mod graph

# Check specific package: go mod graph | grep github.com/dep/lib

# View why dependency is needed: go mod why github.com/dep/lib

# View all dependencies: go list -m all

# Check for updates: go list -u -m all

# View dependency versions: go list -m -versions github.com/dep/lib

# View module info: go mod download -json github.com/dep/lib

# Check import chain: go mod why -m github.com/dep/lib ```

Step 2: Clean Module Cache

```bash # Clear module cache: go clean -modcache

# Remove go.sum: rm go.sum

# Re-download: go mod download

# Tidy dependencies: go mod tidy

# Rebuild: go build ./...

# If using vendor: rm -rf vendor go mod vendor ```

Step 3: Update Dependencies

```bash # Update all dependencies: go get -u ./...

# Update specific package: go get github.com/dep/lib@v1.2.0

# Update to latest: go get github.com/dep/lib@latest

# Update to specific commit: go get github.com/dep/lib@abc123

# Update to specific branch: go get github.com/dep/lib@main

# Update indirect dependencies: go get -u=patch ./...

# Tidy after update: go mod tidy

# Verify: go mod verify ```

Step 4: Use Replace Directive

```go // In go.mod:

module myproject

go 1.21

require ( github.com/example/pkg v1.0.0 github.com/other/lib v2.0.0 )

// Replace with different version: replace github.com/dep/lib => github.com/dep/lib v1.2.0

// Replace with local module: replace github.com/dep/lib => ../local-lib

// Replace with fork: replace github.com/original/lib => github.com/fork/lib v1.0.0

// Multiple replacements: replace ( github.com/dep/lib => github.com/dep/lib v1.2.0 github.com/other/pkg => ../local/pkg ) ```

bash
# After adding replace, update:
go mod tidy

Step 5: Handle Major Version Changes

```go // Go uses major version in import path for v2+:

// v1.x.x: import "github.com/dep/lib"

// v2.x.x: import "github.com/dep/lib/v2"

// v3.x.x: import "github.com/dep/lib/v3"

// In go.mod: require ( github.com/dep/lib v1.2.0 // v1 github.com/dep/lib/v2 v2.3.0 // v2 (different module) )

// If both needed, they're treated as different modules // This avoids most version conflicts ```

```bash # Update to v2+: go get github.com/dep/lib/v2@latest

# Update imports: // Change all imports from "github.com/dep/lib" to "github.com/dep/lib/v2" ```

Step 6: Fix Indirect Dependency Conflicts

```bash # Check indirect dependencies: grep "// indirect" go.mod

# Explicitly set version: go mod edit -require=github.com/dep/lib@v1.2.0

# Or add to go.mod: require github.com/dep/lib v1.2.0

// Then: go mod tidy

# If conflict with indirect: # 1. Update main dependencies to compatible versions # 2. Use replace directive # 3. Check if dependency updates available

# Example: Find minimum compatible version: go mod graph | grep github.com/dep/lib | sort -V | head -5 ```

Step 7: Fix Vendor Issues

```bash # Sync vendor with go.mod: go mod vendor

# Clean vendor and rebuild: rm -rf vendor go mod vendor

# Build with vendor: go build -mod=vendor ./...

# Test with vendor: go test -mod=vendor ./...

# Verify vendor matches: diff -r vendor/github.com/dep/lib <(go mod download -json github.com/dep/lib | jq -r .Dir)

# Update vendor after go.mod change: go mod tidy go mod vendor ```

Step 8: Debug Version Selection

```bash # Enable module debug: GOPROXY=https://proxy.golang.org,direct go mod download

# Check which version selected: go list -m github.com/dep/lib

# Check all versions: go list -m -versions github.com/dep/lib

# Check why version was selected: go mod download -json github.com/dep/lib | jq '.Version, .Time, .GoMod'

# Use verbose output: go get -v -x github.com/dep/lib@v1.2.0

# Check module requirements: go mod edit -json | jq '.Require'

# Check replacements: go mod edit -json | jq '.Replace'

# Minimal version selection explanation: # Go selects the minimum version that satisfies all requirements ```

Step 9: Fix Specific Conflict Patterns

```bash # Pattern 1: Ambiguous import # Error: found package in multiple modules

# Fix: Use explicit version in import or replace replace github.com/dep/lib => github.com/dep/lib v1.2.0

# Pattern 2: Pseudo-version conflict # Error: invalid pseudo-version

# Fix: Use explicit version go get github.com/dep/lib@v1.2.0

# Pattern 3: Incompatible Go version # Error: go directive in go.mod too old

# Fix: Update go directive go mod edit -go=1.21

# Pattern 4: Removed dependency still referenced # Fix: Clean and rebuild go mod tidy go clean -cache

# Pattern 5: Cyclic dependency # Fix: Refactor to remove cycle # Or use interface to break dependency ```

Step 10: Go Module Verification Script

```bash # Create verification script: cat << 'EOF' > /usr/local/bin/check-go-modules.sh #!/bin/bash

PKG=${1:-""}

echo "=== Go Version ===" go version

echo "" echo "=== go.mod Summary ===" head -20 go.mod

echo "" echo "=== Direct Dependencies ===" grep -v "// indirect" go.mod | grep -E "^\s+github.com"

echo "" echo "=== Indirect Dependencies ===" grep "// indirect" go.mod

echo "" echo "=== Outdated Dependencies ===" go list -u -m all 2>/dev/null | grep '[' | head -10

if [ -n "$PKG" ]; then echo "" echo "=== Package: $PKG ===" echo "Why needed:" go mod why $PKG echo "" echo "Available versions:" go list -m -versions $PKG 2>/dev/null | tr ' ' '\n' | head -10 echo "" echo "Current version:" go list -m $PKG fi

echo "" echo "=== go.sum Status ===" wc -l go.sum echo "Unique modules:" cut -d' ' -f1 go.sum | sort -u | wc -l

echo "" echo "=== Vendor Status ===" if [ -d "vendor" ]; then echo "Vendor directory exists" ls vendor | wc -l else echo "No vendor directory" fi

echo "" echo "=== Build Test ===" go build ./... 2>&1 | head -5 || echo "Build failed"

echo "" echo "=== Recommendations ===" echo "1. Run 'go mod tidy' to clean unused dependencies" echo "2. Run 'go get -u' to update dependencies" echo "3. Check 'go mod why <pkg>' for dependency chain" echo "4. Use 'replace' directive for version conflicts" EOF

chmod +x /usr/local/bin/check-go-modules.sh

# Usage: /usr/local/bin/check-go-modules.sh github.com/dep/lib

# Quick check: alias go-deps='go list -m all | head -20' ```

Go Module Checklist

CheckCommandExpected
go.mod validgo mod verifyClean
No conflictsgo mod tidyNo errors
Build succeedsgo build ./...Success
Versions matchgo list -m allConsistent
Vendor syncedgo mod vendorUpdated
Dependencies cleango mod whyAll used

Verify the Fix

```bash # After fixing module conflict

# 1. Clean and rebuild go mod tidy go build ./... // Build succeeds

# 2. Check dependency tree go mod graph | grep conflict-pkg // Single version listed

# 3. Verify go.mod cat go.mod // Replace directives if needed

# 4. Run tests go test ./... // All tests pass

# 5. Check for updates go list -u -m all // No security issues

# 6. Commit changes git add go.mod go.sum git commit -m "fix: resolve module version conflicts" ```

  • [Fix Go Module Not Found](/articles/fix-go-module-not-found)
  • [Fix Go Build Failed](/articles/fix-go-build-failed)
  • [Fix Go Test Failed](/articles/fix-go-test-failed)