Skip to main content

How to Fix 'sf org login web' Authorization Errors in Salesforce CLI

 When working with modern Salesforce DevOps tools, few things disrupt development velocity faster than a Salesforce CLI authorization error. You attempt to authenticate a sandbox or scratch org, but sf org login web fails silently, hangs indefinitely, or throws an obscure EACCES error.

These authentication failures typically stem from local port binding collisions, corrupted state files in your local operating system keychain, or misconfigured routing for enhanced domains. Resolving these issues requires understanding how the Salesforce CLI executes the OAuth 2.0 flow under the hood.

This guide provides technically rigorous solutions to unblock SFDX authentication and restore your local development environment.

Understanding the Root Cause of CLI Authentication Failures

When you execute sf org login web, the CLI initiates an OAuth 2.0 Web Server flow. It does not simply open a browser; it provisions a temporary local web server listening on http://localhost:1717/OauthRedirect. This server waits to intercept the callback payload containing the access and refresh tokens from Salesforce.

Failures generally fall into three architectural categories:

  1. Socket/Port Binding Failures: If port 1717 is occupied by another process, blocked by corporate EDR (Endpoint Detection and Response) software, or trapped inside a WSL2/Docker network partition, the CLI cannot capture the callback. This results in EACCES errors or silent timeouts.
  2. State Corruption (Invalid Grants): The CLI stores encrypted tokens in your operating system's native credential manager (macOS Keychain, Windows Credential Manager) and maintains metadata in local ~/.sf and ~/.sfdx directories. If these tokens expire or the metadata becomes desynchronized, the CLI attempts to use an invalid grant.
  3. Domain Routing Restrictions: With the enforcement of Enhanced Domains, strict URL routing is mandatory. Attempting to log into a sandbox without explicitly targeting the exact My Domain URL causes the OAuth flow to reject the callback.

Solution 1: Bypass Port Binding Issues with Device Authorization

If sf org login web fails due to EACCES errors, port conflicts, or network isolation (such as running the CLI inside a Docker container or WSL2 without port forwarding), the most robust solution is to bypass the local web server entirely.

Instead of the Web Server flow, use the OAuth 2.0 Device Flow. This method relies on a polling mechanism rather than a local HTTP listener.

# Execute the device login flow
sf org login device --instance-url https://test.salesforce.com --alias my-sandbox

Why this works: The CLI will generate a unique 8-character device code and provide a generic Salesforce verification URL. You can open this URL on any device (even your smartphone or a host machine outside the Docker container), enter the code, and authenticate. The CLI actively polls the Salesforce authorization endpoint until the browser flow completes, eliminating the need for localhost:1717 to be exposed.

Solution 2: Purging Corrupted SFDX Authentication State

When you encounter "Invalid Grant", "Expired Token", or a silent failure where the browser completes the login but the CLI never updates, your local configuration state is likely corrupted.

To resolve this, you must aggressively purge both the CLI metadata and the OS-level credential storage.

Step 1: Force a Global Logout

Attempt to use the built-in CLI commands to clean up existing connections.

# Logout of all environments
sf org logout --all --no-prompt

Step 2: Delete Configuration Directories

If the CLI commands fail due to corrupted state, manually delete the hidden configuration directories. The CLI uses both .sf (v2 architecture) and .sfdx (legacy compatibility).

# For macOS / Linux / WSL
rm -rf ~/.sfdx ~/.sf
rm -rf $(pwd)/.sfdx $(pwd)/.sf

# For Windows (PowerShell)
Remove-Item -Recurse -Force ~/.sfdx -ErrorAction SilentlyContinue
Remove-Item -Recurse -Force ~/.sf -ErrorAction SilentlyContinue

Step 3: Clear the OS Credential Manager

The CLI utilizes keytar to store secrets natively. If the files are deleted but the OS keychain retains the keys, the mismatch will cause immediate failures on the next login attempt.

  • macOS: Open Keychain Access, search for sfdx or sf, and delete all matching application passwords.
  • Windows: Open Credential Manager -> Windows Credentials, search for generic credentials starting with sfdx, and remove them.

After clearing these, execute sf org login web again. The CLI will rebuild the configuration directories and store a fresh cryptographic key.

Solution 3: Enforcing Explicit Instance URLs for Enhanced Domains

By default, sf org login web points to login.salesforce.com. If you are authenticating against a sandbox, a scratch org, or a production environment with a strict login policy that prevents generic login routing, the authentication will fail.

You must explicitly declare the exact routing URL using the --instance-url flag.

# Explicitly target a sandbox with a custom My Domain
sf org login web --instance-url https://mycompany--dev1.sandbox.my.salesforce.com --alias dev1

Why this works: Salesforce instances with "Prevent login from https://login.salesforce.com" enabled in their My Domain settings will silently drop or redirect OAuth requests that do not originate from their specific tenant URL. Providing the --instance-url forces the CLI to set the correct aud (audience) and endpoint routing during the initial handshake.

Handling Authentication in CI/CD Environments

A common mistake among developers is attempting to script sf org login web inside continuous integration pipelines. The web flow inherently requires human interaction and a graphical browser.

For headless environments and automated Salesforce DevOps tools, you must transition to JWT (JSON Web Token) authentication or utilize the SFDX Auth URL method.

The JWT Bearer Flow Approach

JWT is the industry standard for server-to-server Salesforce authentication. It requires a Connected App pre-configured with a digital certificate.

# Authenticate headlessly using a JWT grant
sf org login jwt \
  --client-id 3MVG9...[YOUR_CLIENT_ID]... \
  --jwt-key-file assets/server.key \
  --username ci-user@mycompany.com.sandbox \
  --instance-url https://test.salesforce.com \
  --alias ci-org

The Sfdx Auth URL Approach

If maintaining certificates is not viable, you can extract the authentication URL from an active local session and inject it into your pipeline runner as an environment variable.

# 1. On your local machine (where auth is working), display the URL
sf org display --target-org my-sandbox --verbose

# 2. Copy the 'Sfdx Auth Url' output (starts with force://)
# 3. In your CI/CD pipeline, write it to a file and authenticate
echo $SFDX_AUTH_URL_SECRET > authFile.txt
sf org login sfdx-url --sfdx-url-file authFile.txt --alias ci-org

Conclusion

A Salesforce CLI authorization error is rarely a bug in the CLI itself; it is almost always a localized infrastructure issue regarding port availability, stale state data, or domain routing. By leveraging the device login flow for network isolation, meticulously clearing corrupted credential stores, and strictly defining your instance URLs, you can maintain a stable, predictable local environment for your Salesforce DevOps workflows.