The error “The remote server returned an error: (403) Forbidden” indicates that the remote web server, API, or cloud storage system received and recognized the incoming request, but explicitly refuses to authorize access. Unlike a 401 Unauthorized error, a 403 error means authentication was processed, but permission to view or execute the resource is denied.
Quick Answer:
If connecting to a website or REST API, the server is likely blocking Power Query’s default user-agent header. In the formula bar, modify your
Web.Contentscall to include a browser-basedUser-Agentheader. For SharePoint or corporate cloud files, verify that your account has explicit Read access to the destination item.
Why 403 Forbidden Occurs in Power Query
A 403 Forbidden response typically points to one of three issues:
- User-Agent Filtering: Web servers, CDNs (such as Cloudflare or Akamai), and public APIs block requests whose headers identify them as automated scrapers or non-browser clients (such as Power Query’s default client string).
- Missing Object-Level Permissions: The user is logged in with valid credentials, but their account lacks read permissions on that specific file, list, or API endpoint.
- API Key or Parameter Rejection: The API key is valid, but the user’s subscription tier does not have permission to query that specific endpoint or parameter combination.
Solution 1: Add a User-Agent Header to Web Requests
Most web scraping 403 errors occur because the target server rejects requests from Power Query’s default HTTP user-agent. Supplying a standard browser User-Agent header resolves this issue.
The Default Failing Query:
let
Source = Web.Contents("<https://api.example.com/data>")
in
Source
The Corrected Query with Custom Headers:
- In Power Query, select your query and open the Advanced Editor (Home > Advanced Editor).
- Update the
Web.Contentsstep to include aHeadersrecord containing a standard browser user-agent:
let
Source = Web.Contents(
"<https://api.example.com/data>",
[
Headers = [
#"User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
#"Accept" = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
]
]
)
in
Source
- Click Done and refresh the preview.
If passing custom parameters alongside headers produces URL syntax breaks, review Troubleshooting Web.Contents errors: “The provided URI scheme is invalid.”
Solution 2: Fix Cloud Storage and SharePoint Permissions
When connecting to SharePoint Online, OneDrive, or Azure Blob storage, a 403 Forbidden error means your identity token is valid, but the target server’s access control list (ACL) denies you access.
[User Token: Verified via Microsoft Entra ID]
│
▼
[Target Resource: /sites/Finance/Confidential_Budget.xlsx]
│
Does user have Read permission?
/ \
(YES) (NO)
│ │
Data Returns HTTP 403 Forbidden
Diagnostic Steps for Cloud Files:
- Verify Browser Access: Open an incognito browser window, navigate directly to the file URL, and sign in with the exact account used in Power Query. If the browser displays “You need permission to access this site,” your account lacks access. Contact the site administrator to request Read access.
- Clear Stale Credentials: If you have permission in the browser but Power Query returns a 403, Excel is likely using an older token that lacks the newly assigned role. Clear the connection cache via Data > Get Data > Data Source Settings using the steps in Managing Data Source Settings: How to clear and reset Global Permissions.
- Re-authenticate via OAuth: Reconnect using your Organizational Account following the process detailed in Power Query and OAuth2: Fixing “The credentials provided for the source are invalid.”
Solution 3: API Keys and Authorization Headers
If you are querying a REST API that requires token authorization, ensure the token is formatted according to the service’s API specifications:
- Bearer Tokens: Many modern APIs require the word
Bearerpreceding the token string:Headers = [Authorization = "Bearer " & YourSecretToken] - Custom Header Names: Some services reject the standard
Authorizationheader and require custom headers such asx-api-keyorApiKey:Headers = [#"x-api-key" = "your_actual_key_here"]
If the API requires matching privacy rules before executing alongside local data tables, ensure you configure the connection’s privacy levels as outlined in How to fix Privacy Level Mismatches: Public vs. Organizational vs. Private.