Hotlink Protection in NGINX Without Blocking Google Images

In this article
- What Is Image Hotlinking and How Does NGINX Detect It?
- How NGINX valid_referers Works
- A Safe Hotlink Protection Config, Step by Step
- Why Empty Referers Must Stay Allowed
- How to Keep Images in Google Images
- Checking Your Logs After Enabling Hotlink Protection
- Where Hotlink Protection Fits With Caching and Bot Limits
- FAQ
Hotlink protection in NGINX lets image requests through only when the Referer header is empty, points to your own domains or comes from a search engine. Everything else gets rejected with the valid_referers directive. The point? Stopping other sites from embedding your files and making your server pay to deliver them (people call this image bandwidth theft). The real danger isn’t the thieves, though. It’s a rule that’s too strict, because that can quietly make your pictures disappear from Google Images. Everything below lives on your own origin NGINX.
What Is Image Hotlinking and How Does NGINX Detect It?
Someone drops your image URL into their own <img> tag. Now your server delivers the file to their visitors. That’s hotlinking. When a browser loads that page it usually sends a Referer header with the address of the embedding page, and NGINX can check it against an allowlist. But the header is a hint. Nothing more. Browsers and proxies can leave it out or strip it, so it never counts as real authentication. What you get is an end to casual embedding on other sites. Someone who deliberately wants your files? They’ll still get them.
How NGINX valid_referers Works
The valid_referers directive sets the $invalid_referer variable. Then an if block returns 403 (or a placeholder) for any request that doesn’t match. The example in the NGINX referer module documentation packs every parameter type into one line:
valid_referers none blocked server_names *.example.com example.* www.example.org/galleries/ ~\.google\.;- none covers requests with no Referer header at all.
- blocked covers headers that exist but got emptied by a proxy or firewall.
- server_names covers whatever sits in your
server_namedirective. List both www and non-www, plus any subdomain or CDN hostname that serves your pages. - Wildcards like
*.example.comand regexes starting with~handle wider patterns, search engine domains included.
A Safe Hotlink Protection Config, Step by Step
Safe here means three things: check image files only, let empty and trusted referers through, and hand everything else a plain 403. The steps:
- Create a location that matches only image extensions.
- Add
valid_referers none blocked server_names, then your own domains and~\.google\.. - Add
if ($invalid_referer) { return 403; }. - Run
nginx -t, then reload NGINX. - Test with curl, sending different Referer headers.
location ~* \.(jpg|jpeg|png|gif|webp|avif|svg)$ {
valid_referers none blocked server_names
example.com www.example.com
~\.google\.;
if ($invalid_referer) {
return 403;
}
}Your HTML pages aren’t affected, since the rule only touches image files. Should you swap in a cheeky “stolen image” graphic instead of the 403? I wouldn’t. A plain 403 is simpler to maintain and doesn’t mislead anyone about what the file actually is. Then test four cases: no Referer, your own domain, a Google domain and a foreign domain. For example, curl -I -e https://other-site.test/ https://example.com/photo.jpg should come back 403, and the same request without -e should give you 200.
Why Empty Referers Must Stay Allowed
Block requests with no Referer and you cut off real users and crawlers. So none and blocked aren’t optional. Who sends no Referer? People typing a URL directly, strict privacy settings, bookmarks, feed readers, crawlers. And Googlebot-Image fetches files without a referring page, which means a rule missing none locks it out completely. The usual mistakes:
- leaving out
noneorblocked, - forgetting the www variant of your domain,
- applying the check to the whole site instead of the image location,
- a Google regex so narrow that it misses country domains.
How to Keep Images in Google Images
Google has to be able to fetch the exact file a user sees. So no special exception for Googlebot-Image and no different response either. Serving crawlers something other than what people get is cloaking, plain and simple. Your rule should treat every client the same way and differ only by Referer. According to Google’s image SEO guidelines, Google finds images in the standard <img src> attribute, accepts image sitemaps, supports formats including WebP, SVG and AVIF, and doesn’t index CSS background images. Want to limit how full-size files get displayed? The official route is opting out of inline linking in Google Images, and Google says that isn’t treated as image cloaking.
Checking Your Logs After Enabling Hotlink Protection
Rule deployed. Now go through the image requests that got a 403 in your access logs and make sure none came from your own site or from Google. Filter by status, $http_referer, user agent and image path. First time digging through these? Our guide to reading image requests in access logs walks through the fields. If images start vanishing from Google Images, pull the regex and the if block for a while, then compare logs before and after to see which referer got rejected.
Where Hotlink Protection Fits With Caching and Bot Limits
The referer check runs independently of caching and rate limiting. But the order of rules in your config decides what a crawler actually receives. If there’s a cache in front of your origin, a 403 triggered by a foreign Referer must never get stored and then served to everyone (that one hurts). Review your caching rules for crawlers so those responses stay separate. And for aggressive scrapers, rate limits beat stricter referer rules every time. There are ways of throttling bots without harming Googlebot.
Build your hotlink protection on none, blocked, server_names and Google domains, and you stop other sites from embedding your images while they stay visible in search results.
FAQ
Will hotlink protection remove my images from Google Images?
No, as long as requests with no Referer and Google domains are allowed. Apply the same rule to every visitor and crawler, and Googlebot-Image keeps fetching your files like before.
Should I whitelist Googlebot-Image by user agent?
No. The Referer rule does the job, because the crawler sends no referring page and none already lets it in. Handling crawlers separately just invites cloaking trouble.
Can hotlink protection stop someone from downloading my images?
No. It only blocks embedding on other sites. Anyone can forge or drop the Referer header, so a direct download still works.


