Quick Diagnosis: Match the Error to the Cause
Hover over the red triangle on the #N/A or #REF! cell to see the exact message, then find it here:
| Error message | What it usually means | First thing to try |
|---|---|---|
| Could not fetch url: https://... | Google's servers couldn't download the page: the site blocked them, the URL needs a login, it redirects or times out, or Google's fetcher had a temporary failure | Open the URL in a private window; if it works there, the site is probably blocking Google's fetcher |
| Imported content is empty | The page downloaded, but your XPath matched nothing in the raw HTML. Usually the data is added by JavaScript, or the XPath was copied from Inspect | Search View page source for the value you want |
| Imported Xml content can not be parsed | The XPath has a syntax error, or the response isn't valid XML/HTML (e.g. a JSON or PDF URL) | Check quotes and brackets in the XPath; use single quotes inside the double-quoted formula |
| Resource at url not found | The server answered with an error such as 404 for that URL | Check the URL for typos, tracking parameters or a page that moved |
| Result too large | Your XPath returns more data than Sheets will import in one call | Narrow the XPath to the elements you need |
| Loading... that never finishes, or "Loading data may take a while because of the large number of requests" | Too many IMPORT functions in the spreadsheet | Cut the number of IMPORT calls (see below) |
Google's own help page on import functions documents the "large number of requests" and "Result too large" messages; the rest come from how the fetcher behaves in practice. The same causes apply to IMPORTHTML, IMPORTDATA and IMPORTFEED.
"Could Not Fetch URL": Causes and Fixes
IMPORTXML doesn't fetch from your computer. Google's servers request the page, so anything that blocks or confuses an automated request from a Google data centre produces this error, even when the page opens fine in your browser.
1. The site blocks Google's fetcher
This is the most common cause on big sites. Shops, marketplaces, ticketing, social and finance sites often run bot protection (Cloudflare and similar) that returns a 403 or a challenge page to requests that don't look like a person in a browser. Every IMPORTXML user shares Google's fetchers, so popular sites see heavy traffic from them and many block it. A tell-tale sign: =IMPORTXML("https://example.com","//title") fails on that domain but works on others.
Fix: there's no setting in Sheets that changes how Google identifies itself. Use the site's API or export if it has one, or fetch the page with something that behaves like a real browser (see the last section).
2. Rate limiting
Dozens of IMPORTXML cells pointing at the same domain fire at once. The site may answer the first few and refuse the rest, which is why errors often appear on some rows and not others, or come and go. Fix: fewer calls (one IMPORTXML that returns a whole column instead of one per row), and fewer URLs per sheet.
3. Login, consent or region pages
Pages behind a login can't be fetched: Google's servers don't have your cookies. Some sites also show a cookie-consent wall, a country selector or a different page to visitors from another region, and Google fetches from its own data centres, not from where you are. Fix: nothing in Sheets can sign in for you. Look for a public version of the page, a shareable export link, or switch to a browser-based tool that can log in.
4. The URL itself
- Typos, spaces or line breaks pasted into the URL cell. Wrap it in
TRIM(). - Missing
https://. - Very long URLs with tracking parameters; strip everything after
?that the page doesn't need. - Pages that redirect several times or load slowly can time out.
5. robots.txt and Google-side hiccups
Some users report imports failing on sites whose robots.txt disallows automated access, and the error is also sometimes intermittent, with the same URL working an hour later. Google doesn't document either behaviour, so treat them as things to rule out last, after checking the causes above.
"Imported Content Is Empty": Causes and Fixes
This one means the fetch worked, but your XPath found nothing in what Google received.
1. The data is rendered by JavaScript (most common)
IMPORTXML and IMPORTHTML read the HTML the server sends before any JavaScript runs. Prices, stock levels, search results and tables on modern sites are often inserted later by scripts calling an API. You see them in the browser; IMPORTXML never does.
Test: right-click the page, choose View page source (not Inspect), and Ctrl+F for a value you can see on screen. If it's not in the source, no XPath will reach it with IMPORTXML. Our guide to scraping dynamic websites explains the alternatives in depth.
2. The XPath was copied from Inspect
"Copy XPath" in DevTools describes the rendered DOM, which can differ from the raw HTML:
- Browsers insert
<tbody>into tables even when the source has none. Remove/tbodyfrom the path or use//table//tr. - Absolute paths like
/html/body/div[3]/div[2]/spanbreak if one element is added. Prefer attributes://span[@class='price'], or//span[contains(@class,'price')]when the element has several classes. - Elements added by scripts (banners, injected wrappers) change the positions in the copied path.
3. The page Google gets is different
A consent page, a "choose your country" page or a bot challenge has no element matching your XPath. Test with =IMPORTXML(A1,"//title"): if the title is "Just a moment...", "Access denied" or a consent message, you're looking at the blocking problem from the previous section.
4. The value is in an attribute or a script
Use //a/@href or //meta[@property='og:price:amount']/@content for attributes. If the value only appears inside a <script> block (JSON on the page), you can sometimes pull it with REGEXEXTRACT(IMPORTXML(A1,"//script[@type='application/ld+json']"),"price.:.?([0-9.]+)"). It's fragile, but it's free.
IMPORTHTML Not Working
IMPORTHTML(url, "table", n) has the same fetch limits plus two of its own:
- Wrong index.
ncounts<table>(or<ul>/<ol>for "list") elements in the raw HTML, starting at 1, including invisible layout tables. Try 1, 2, 3... until the right one appears. - Not a real table. Many "tables" on modern sites are built from
<div>s with CSS grid. IMPORTHTML only sees real<table>elements; use IMPORTXML with an XPath on the divs instead.
Too Many IMPORT Calls: "Loading..." Forever
Google limits the traffic import functions can create. When a spreadsheet has many of them, cells sit on Loading... or show the "large number of requests" message. Third-party guides often quote a fixed limit, but Google doesn't publish a single number. What helps:
- One call, many results. An XPath like
//div[@class='item']//h3returns every match down a column. One formula instead of 100. - Don't import the same URL twice. Fetch it once and reference those cells, or use
INDEX()on one result. - Freeze results you don't need live. Copy and Paste special > Values only, so old rows stop re-fetching.
- Split across files if you genuinely need hundreds of URLs, or move the fetching out of formulas.
Note also that you can't control when IMPORTXML refreshes. Sheets re-fetches on its own schedule, so it's poor at "check this price every morning and keep a history".
When to Stop Fighting IMPORTXML
IMPORTXML is great for static, public pages and a handful of values. Switch tools when any of these are true:
- The value isn't in View page source (JavaScript-rendered).
- The site blocks Google's fetcher, and errors won't go away.
- The page needs a login, a click, a search or scrolling first.
- You need a dated history (one row per run), not a value that silently refreshes.
- You need more than a few dozen URLs.
Your options:
- Apps Script with UrlFetchApp gives you control over timing and writes values (not formulas), but it is still a plain HTTP fetch from Google: no JavaScript, and the same blocking. It works well when the site has a public JSON API you can call.
- Your own script (Python with Playwright) renders the page in a real browser and writes to Sheets through the Sheets API. Full control, but you host and maintain it.
- A browser-based scraper that writes to Sheets, such as the option below.
Using a Browser-Based Scraper That Writes to Google Sheets
Autonoly runs a real Chromium browser in the cloud, so it sees the page after JavaScript has run, and it has a native Google Sheets integration.
For a one-off or ad-hoc pull, ask the agent. For example: "Open these 40 product URLs from column A of my 'Watchlist' sheet, get the current price and stock status from each, and write them to the 'Prices' tab with today's date." The agent handles pages that need scrolling, clicking or a login (it can ask you for credentials), and you can watch it in the live view.
For a recurring pull, save a scheduled workflow:
- Launch Browser on the page.
- Wait For the element that holds your data.
- Extract Data for single values, Extract Table for tables, or Extract Child Collection for repeated items such as product cards. Selectors can be CSS or the same XPath you used in IMPORTXML.
- Google Sheets (write), which appends rows by default, so each run adds a dated snapshot instead of overwriting.
- Run it on a schedule, for example every weekday at 8:00 in your timezone.
Be realistic about the limits: saved workflows can't sign in with stored credentials (so pages behind a login are an agent task), there's no proxy rotation, and sites with strong bot protection may still show a challenge. reCAPTCHA v2 and hCaptcha can be solved when enabled; other challenges are handed to you via live takeover. Each workflow covers a fixed set of pages, since there's no loop step; for a long, changing list of URLs, use the agent. See data extraction for the details.