The Problem
You have a formula like this in Google Sheets:
=IMPORTDATA("https://example.com/data.csv")
Instead of loading data, the cell shows:
Could not fetch url: https://example.com/data.csv
Google Sheets tried to reach that URL โ and failed. Either the URL is unreachable from Google's servers, the resource doesn't exist, or the server refused the request outright.
Why This Happens
Here's the part that trips most people up: Google Sheets fetches URLs using Google's own servers, not your browser. A URL can work perfectly in Chrome and still fail in Sheets. The reasons fall into a few buckets:
- The URL requires authentication โ private API endpoints, token-protected resources, or login-gated pages all fail silently.
- The server blocks Google's IP ranges โ some servers have bot-blocking rules that reject requests originating from Google's datacenter IP blocks (e.g., 66.249.x.x).
- Wrong content type โ IMPORTDATA only handles plain CSV or TSV. Point it at JSON, XML, or an HTML page and it will always error.
- Dead or expired URL โ typos, broken links, or pre-signed URLs that expired after 15 minutes all look the same to Sheets.
- Redirect chains โ too many hops, or an HTTPโHTTPS redirect that Sheets can't follow.
- Server-side bot blocking โ some services explicitly reject non-browser User-Agent strings.
Quick Checks First
1. Verify the URL is truly public
Open it in an incognito window โ no cookies, no session. If the page asks you to log in or returns a 403, that's your answer. Google Sheets sees exactly what an anonymous visitor sees.
2. Simulate a non-browser request with curl
curl -I "https://example.com/data.csv"
A 403 Forbidden or 401 Unauthorized here means the server is blocking non-browser clients. Google Sheets will hit the same wall.
3. Check what content type the server returns
curl -s -o /dev/null -w "%{content_type}" "https://example.com/data.csv"
IMPORTDATA expects text/csv or text/tab-separated-values. If you see application/json or text/html, switch to the right import function (see Fix 4 below).
Fix by Cause
Fix 1: Use a direct, public CSV/TSV URL
The URL must be publicly accessible โ no login, no token โ and return raw CSV or TSV. A GitHub raw file URL is a reliable example:
=IMPORTDATA("https://raw.githubusercontent.com/user/repo/main/data.csv")
Watch out: use the raw URL, not the file preview page. The preview page returns HTML, not CSV.
Fix 2: Google Drive โ use the export URL
Data living in Google Sheets or Drive? Use the export endpoint directly:
=IMPORTDATA("https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/export?format=csv&gid=SHEET_GID")
Replace SPREADSHEET_ID and SHEET_GID with your actual values. The source spreadsheet must be shared as "Anyone with the link can view" โ otherwise you'll get a 403 right back.
Fix 3: The server blocks Google โ proxy the request
If you own the data source, whitelist Google's IP ranges or loosen bot-blocking rules for that endpoint. If you don't control the server, you have two options.
Option A: route through a public CORS proxy (only for non-sensitive, public data). Option B: spin up a small middleware service:
# Minimal Flask proxy
from flask import Flask, Response, request
import requests
app = Flask(__name__)
@app.route("/proxy")
def proxy():
url = request.args.get("url")
r = requests.get(url)
return Response(r.content, content_type="text/csv")
Then point Sheets at your own endpoint:
=IMPORTDATA("https://yourproxy.com/proxy?url=https://example.com/data.csv")
Fix 4: Switch functions for non-CSV sources
IMPORTDATA is only for CSV and TSV. If the URL returns HTML or XML, you need a different function:
=IMPORTHTML("https://example.com/table-page", "table", 1)
=IMPORTXML("https://example.com/feed.xml", "//item/title")
Fix 5: Bust the cached error
Sheets sometimes caches a fetch error even after the URL becomes accessible again. Two ways to force a refresh:
- Append a dummy parameter to the URL: change
?t=1to?t=2to force re-evaluation. - Go to File โ Settings โ Calculation โ On change and every hour to trigger periodic refreshes.
=IMPORTDATA("https://example.com/data.csv?nocache=" & TEXT(NOW(), "YYYYMMDDHHMMSS"))
The NOW() trick works for debugging โ it recalculates on every sheet change. Remove it once the data loads correctly, or your sheet will hammer the server on every keystroke.
Permanent Fix โ Host Your Data Somewhere Reliable
If IMPORTDATA is central to your workflow, park your CSV somewhere built for anonymous public access:
- GitHub raw URLs โ free, no auth needed for public repos, consistently reliable
- Google Drive + export URL โ the
/export?format=csvpattern above, shared publicly - AWS S3 public bucket โ set the object ACL to
public-readand use the direct S3 URL - Cloudflare R2 โ same idea, cheaper egress than S3 for high-traffic files
Verify the Fix
- Update the formula or URL, then wait 10โ15 seconds for Sheets to fetch.
- The error cell should be replaced with actual data rows.
- Check cell A1 of the imported range โ it should show your CSV header's first field.
- Seeing
#N/Ainstead of the fetch error? The URL loaded, but the data format is off โ check delimiter settings or whether the file has a BOM character.
Still failing after using a correct public URL? Run a fresh curl request from a server outside your local network. That confirms whether the URL is genuinely public or only accessible from your IP range.

