How to fix W: Failed to fetch URL 401 Unauthorized in APT

APTINTERMEDIATEHIGHUpdated Dec 29, 2025· 262 views

This error occurs when APT cannot authenticate to a package repository that requires credentials. Common causes include missing subscription credentials for enterprise repositories (like Proxmox), expired authentication tokens, or misconfigured repository URLs with invalid credentials.

Quick fix

Fixes 401

sudo apt update
  1. Check which repository is causing the 401 error
  2. For Proxmox users: Disable enterprise repository and enable no-subscription repo
  3. Configure credentials using /etc/apt/auth.conf
  4. Fix embedded credentials with special characters
apt — error
sudo apt update
W: Failed to fetch URL 401 Unauthorized

What this error means

The "W: Failed to fetch URL 401 Unauthorized" warning indicates that APT attempted to access a repository that requires authentication, but the provided credentials were invalid, missing, or expired. HTTP 401 Unauthorized is a standard status code meaning the server requires authentication and either: - No authentication credentials were provided in the repository URL - The credentials (username/password or token) are incorrect - The authentication token has expired - The subscription license is no longer valid - Basic authentication is not enabled on the repository This commonly occurs in several scenarios: - **Proxmox Enterprise Repository**: The default Proxmox VE installation includes the enterprise repository URL, which requires a valid subscription. Without a subscription key, all update attempts fail with 401. - **Private Debian/Ubuntu repositories**: Custom repositories hosted on internal servers or cloud services (Gemfury, Artifactory, Nexus) that require authentication tokens or credentials. - **Token-based authentication**: Repositories like GitHub Packages that use OAuth tokens instead of traditional usernames and passwords. - **Expired credentials**: If credentials or tokens were stored but have since expired or been revoked. The error is prefixed with "W:" (warning) rather than "E:" (error), meaning apt continues attempting other repositories but this one fails.

Typical symptoms

  • apt update fails with 'W: Failed to fetch' followed by a URL and '401 Unauthorized'
  • Error only appears for specific repositories, not all sources
  • Proxmox/PVE systems show 401 errors on enterprise.proxmox.com URLs
  • Private repository sources fail to authenticate
  • apt-get upgrade attempts but skips problematic repositories
  • CI/CD pipelines fail when pulling from authenticated repositories
  • Error includes the full repository URL being accessed

Common causes

  1. Proxmox Enterprise repository enabled without valid subscription
  2. Missing or invalid credentials in repository URL
  3. Authentication token has expired or been revoked
  4. Subscription license no longer valid or needs renewal
  5. Incorrect username or password in sources.list entries
  6. Repository requires /etc/apt/auth.conf configuration that is missing
  7. URL-embedded credentials contain special characters that need URL encoding
  8. Repository hostname changed or URL is outdated
  9. Private repository requires specific authentication header or mechanism

How to fix "W: Failed to fetch URL 401 Unauthorized"

1Check which repository is causing the 401 error

First, identify the exact repository URL that's failing. The error message should show it:

bash
sudo apt update

Look for output like:

bash
W: Failed to fetch https://enterprise.proxmox.com/debian/pve/dists/bookworm/InRelease 401 Unauthorized

Write down the failing repository URL. In this example, it's https://enterprise.proxmox.com/debian/pve/.

Check your sources list files:

bash
# Check main sources.list
cat /etc/apt/sources.list | grep -v '^#'

# Check additional source lists
ls /etc/apt/sources.list.d/
cat /etc/apt/sources.list.d/*.list 2>/dev/null | grep -v '^#'

The failing URL will be in one of these files. This helps you determine which repository needs fixing.

2For Proxmox users: Disable enterprise repository and enable no-subscription repo

If you're using Proxmox VE without a subscription, the enterprise repository will always fail with 401. You have two options:

Option 1: Use the GUI (Recommended for beginners)

1. Open Proxmox web interface (https://your-proxmox-ip:8006)
2. Navigate to: Datacenter → Nodes → [YOUR-NODE] → Updates → Repositories
3. You'll see several repository entries
4. Find the one with URL https://enterprise.proxmox.com/...
5. Click the row to select it, then click the "Disable" button (or eye icon to hide)
6. Look for "Proxmox VE No-Subscription" repo - enable it if not already enabled
7. Close the dialog and run apt update again

Option 2: Edit configuration files directly

Disable the enterprise repository:

bash
sudo nano /etc/apt/sources.list.d/pve-enterprise.list

Comment out or delete the line:

bash
# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise

Then add the no-subscription repository to your main sources.list:

bash
sudo nano /etc/apt/sources.list

Add this line:

bash
deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
deb http://deb.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware

# Proxmox VE No-Subscription repository
deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription

Option 3: If you have a valid subscription

If you actually have a Proxmox VE subscription, verify your subscription key:

1. Open Proxmox web interface
2. Go to Datacenter → Subscription
3. Check if a subscription is active
4. If expired or missing, click "Register Subscription" or "Check" to validate

Once valid, the enterprise repository should authenticate successfully.

After making changes, test:

bash
sudo apt update
3Configure credentials using /etc/apt/auth.conf

For private repositories that require authentication, use the /etc/apt/auth.conf file instead of embedding credentials in sources.list.

Create or edit the auth file:

bash
sudo nano /etc/apt/auth.conf

Add credentials in this format:

bash
machine repo.example.com
login username
password your-password

Or for token-based authentication (like GitHub):

bash
machine github.com
login oauth2
password ghp_xxxxxxxxxxxxxxxxxxxx

For multiple repositories:

bash
machine repo1.example.com
login user1
password pass1

machine repo2.example.com
login user2
password pass2

Set proper permissions (CRITICAL):

bash
sudo chmod 600 /etc/apt/auth.conf

The file must be readable only by root. If permissions are wrong, APT will ignore it.

Update your sources.list to remove embedded credentials:

Before:

bash
deb https://username:password@repo.example.com/debian bookworm main

After:

bash
deb https://repo.example.com/debian bookworm main

APT will automatically use credentials from auth.conf when accessing the repository.

Test the configuration:

bash
sudo apt update
4Fix embedded credentials with special characters

If you must embed credentials directly in sources.list, special characters in passwords must be URL-encoded.

Special characters that need encoding:

| Character | URL Encoding |
|-----------|--------------|
| @ | %40 |
| : | %3A |
| / | %2F |
| # | %23 |
| ? | %3F |
| & | %26 |
| = | %3D |
| % | %25 |

Example with encoded password:

If your password is pass@word#123, encode it as pass%40word%23123

Wrong (will fail with 401):

bash
deb https://user:pass@word#123@repo.example.com/debian bookworm main

Correct:

bash
deb https://user:pass%40word%23123@repo.example.com/debian bookworm main

To URL-encode a password in bash:

bash
python3 -c "import urllib.parse; print(urllib.parse.quote('pass@word#123', safe=''))"

However, using /etc/apt/auth.conf is strongly recommended over embedding credentials in source URLs.

5Check repository authentication token expiration

For repositories using token-based authentication (GitHub Packages, GitLab, etc.), verify the token hasn't expired:

For GitHub Packages:

bash
# Token should be a Personal Access Token (classic or fine-grained)
# Check token expiration at: https://github.com/settings/tokens

# Example sources.list entry:
# deb https://username:TOKEN@github.com/owner/repo-name/debian bookworm main

For GitLab Package Registry:

bash
# Token should be a Personal Access Token or Deploy Token
# Check token expiration at: https://gitlab.example.com/-/profile/personal_access_tokens

# Example:
# deb https://gitlab-ci-token:CI_JOB_TOKEN@gitlab.example.com/api/v4/projects/1234/packages/deb bookworm main

Check if token is expired:

1. Go to your token management page in the service (GitHub, GitLab, etc.)
2. Look for "Expiration" or "Expires at" field
3. If expired, generate a new token
4. Update your sources.list or auth.conf with the new token
5. Run sudo apt update to test

For services with token expiration:

bash
# Regenerate token regularly in automation
# Or use tokens without expiration if available
6Verify repository URL and hostname

Typos or outdated repository URLs will cause authentication failures:

Check if the repository is still active:

bash
# Test the repository with curl
curl -v https://repo.example.com/debian/Release

# If you get 401, test with credentials
curl -u username:password https://repo.example.com/debian/Release

Common repository URL changes:

Some repositories move or change their URLs. Check if your sources.list has old URLs:

Outdated URLs:
- deb https://archive.ubuntu.com/ubuntu → deb http://archive.ubuntu.com/ubuntu
- deb https://ppa.launchpad.net/some-old-ppa → May have been removed entirely
- deb https://deb.example.com → May have moved to deb https://packages.example.com

To verify a repository is still active:

bash
# Check the Releases file without authentication
curl -i https://repo.example.com/debian/dists/bookworm/Release

# 401 means you need credentials
# 404 means the repository no longer exists
# 200 means it's accessible

Update sources.list if needed:

bash
sudo nano /etc/apt/sources.list.d/myrepo.list

# Update the URL to the correct one
# deb https://old-repo.example.com/debian bookworm main
# deb https://new-repo.example.com/debian bookworm main

Then test:

bash
sudo apt update
7Check APT auth.conf permissions and APT version

APT won't use auth.conf if permissions are wrong, or if using an older APT version that doesn't support it.

Verify auth.conf has correct permissions:

bash
ls -l /etc/apt/auth.conf

Output should look like:

bash
-rw------- 1 root root 1024 Jan  1 10:00 /etc/apt/auth.conf

If it shows -rw-r--r-- (world-readable), APT ignores it. Fix with:

bash
sudo chmod 600 /etc/apt/auth.conf

Check if your APT version supports auth.conf:

bash
apt --version

auth.conf support was added in APT 0.7.25 (released in 2008), so virtually all modern systems have it. If you're on an extremely old system, consider updating.

Verify APT is reading auth.conf:

Enable APT debugging:

bash
sudo apt update -o Debug::Acquire::http=true 2>&1 | grep -i auth

You should see APT attempting to use the credentials from auth.conf.

If auth.conf is still not working:

Try embedding credentials directly (less secure but works for testing):

bash
# Edit sources.list temporarily
sudo nano /etc/apt/sources.list.d/test.list

# Add: deb https://username:password@repo.example.com/debian bookworm main
# (use URL-encoded password if it has special characters)

sudo apt update

If this works, the issue is with auth.conf. If this also fails, the problem is with the credentials themselves.

8Check network connectivity and firewall

Sometimes 401 errors mask network connectivity issues. Verify you can reach the repository:

Test basic connectivity:

bash
# Ping the repository host
ping -c 3 repo.example.com

# Or use ping with DNS:
nslookup repo.example.com

Test HTTPS connectivity:

bash
# Check if HTTPS port is open
curl -v https://repo.example.com/debian/Release 2>&1 | head -20

# This should show either:
# - SSL/TLS handshake details
# - 401 Unauthorized (good - you can reach it)
# - Connection timeout (network issue)
# - Connection refused (host or firewall blocking)

If behind a corporate proxy:

Configure APT to use the proxy:

bash
sudo nano /etc/apt/apt.conf.d/proxy.conf

Add:

bash
Acquire::http::Proxy "http://proxy.example.com:8080";
Acquire::https::Proxy "http://proxy.example.com:8080";

Or with credentials:

bash
Acquire::http::Proxy "http://username:password@proxy.example.com:8080";

Check firewall rules:

bash
# On the APT client machine, check if 443 is open to the repository
sudo iptables -L -n | grep HTTPS

# Or use nc (netcat) to test connectivity
nc -zv repo.example.com 443

If the server is unreachable, you'll see "Connection refused" or "timed out" rather than 401.

Advanced notes

Understanding HTTP 401 vs other failures:

When apt shows "401 Unauthorized", it means the server received the request and explicitly rejected it due to missing/invalid credentials. This is different from:

- 403 Forbidden: Authentication succeeded, but user lacks permission (credentials valid but insufficient)
- 404 Not Found: Repository URL is wrong or no longer exists
- Connection refused: Network or firewall issue, server not reachable
- SSL errors: TLS/certificate issues, not authentication

APT authentication mechanism details:

APT supports two authentication methods:

1. HTTP Basic Auth: Username and password in URL or auth.conf
- Requires HTTPS for security
- Supported since APT 0.7.25 (2008)
- Uses Authorization header with Base64-encoded credentials

2. Netrc-style configuration: auth.conf file
- More secure (credentials not in source list files)
- Applied per-host from auth.conf
- APT reads this automatically if permissions are correct

Why Proxmox shows 401 specifically:

Proxmox enterprise repositories use API key authentication. When you subscribe:

1. You receive a subscription key
2. During Proxmox setup, this key is registered in the web interface
3. Proxmox adds a proxy certificate to your system
4. APT uses this certificate to authenticate to enterprise.proxmox.com

Without a subscription key:
- No certificate is provisioned
- Repository requests are unauthenticated
- Proxmox returns 401
- APT shows "Failed to fetch 401 Unauthorized"

Private repository patterns:

Different hosting services use different authentication methods:

| Service | Pattern | Auth Method |
|---------|---------|-------------|
| Proxmox | https://enterprise.proxmox.com/... | Certificate (subscription) |
| GitHub Packages | https://token@github.com/org/repo/... | Personal Access Token |
| GitLab | https://gitlab-ci-token:TOKEN@gitlab.com/api/v4/... | Deploy/Personal Token |
| Gemfury | https://token@gemfury.com/apt/yourname/... | API Token |
| Nexus | https://nexus.example.com/repository/apt | Basic auth or token |

Best practices:

1. Always use HTTPS with credentials
2. Use /etc/apt/auth.conf instead of embedding in sources.list
3. Rotate tokens regularly
4. Use minimal-scope tokens (GitHub Fine-Grained, GitLab Deploy Token)
5. Never commit sources.list with credentials to version control
6. Monitor token expiration dates to prevent surprise failures

Frequently asked questions

What does "401" mean?
The "W: Failed to fetch URL 401 Unauthorized" warning indicates that APT attempted to access a repository that requires authentication, but the provided credentials were invalid, missing, or expired. HTTP 401 Unauthorized is a standard status code meaning the server requires authentication and either: - No authentication credentials were provided in the repository URL - The credentials (username/password or token) are incorrect - The authentication token has expired - The subscription license is no longer valid - Basic authentication is not enabled on the repository This commonly occurs in several scenarios: - Proxmox Enterprise Repository: The default Proxmox VE installation includes the enterprise repository URL, which requires a valid subscription. Without a subscription key, all update attempts fail with 401.
How do I fix "401"?
This error occurs when APT cannot authenticate to a package repository that requires credentials. Common causes include missing subscription credentials for enterprise repositories (like Proxmox), expired authentication tokens, or misconfigured repository URLs with invalid credentials.
What causes "401"?
Proxmox Enterprise repository enabled without valid subscription Missing or invalid credentials in repository URL Authentication token has expired or been revoked
Is the "401" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading