How to Fix '403 Forbidden' on Vercel Hosted Images (2025)
Vercel images not loading? Learn how to fix '403 Forbidden' by configuring remotePatterns in your next.config.js and whitelisting external domains.
FlowQL Team
AI Search Optimization Experts
You’ve built a dynamic dashboard that pulls user profile pictures from Google or social media. Locally, your images load perfectly. But the moment you deploy to Vercel, your site is filled with broken image icons and a red "403 Forbidden" error in the network tab.
This is the "External Domain Wall."
Vercel's next/image component is incredible—it automatically resizes, compresses, and optimizes your images for every device. But because this process happens on Vercel’s servers (using their compute and bandwidth), they don't allow just any image to be optimized. If you haven't explicitly "trusted" the external source, Vercel will block the request to prevent people from using your Vercel account to optimize images for their own sites.
For "Vibe Coders" using AI to generate UI, this is a top-tier frustration. The AI writes the code to "Show the user avatar," but it doesn't know that your production environment requires a specific security whitelist to function.
In this guide, we’ll show you how to configure the remotePatterns protocol, fix the common "Hotlinking" issues, and ensure your images load flawlessly on Vercel.
Why Vercel Returns 403 for External Assets
To fix the icon, you have to understand the security model.
When you use <Image src="https://example.com/photo.jpg" />, Next.js doesn't just send that URL to the browser. It sends a request to a Vercel Image Optimization API (/_next/image?url=...).
Vercel's server then:
- Downloads the image from
example.com. - Optimizes it.
- Serves it to your user.
If example.com isn't in your whitelist, Vercel refuses to perform Step 1 and returns a 403. This protects you from "Image Proxy" attacks where malicious actors could run up your Vercel bill by proxying millions of images through your site.
The next.config.js remotePatterns Protocol
The solution is to tell Next.js exactly which external domains are safe. In modern Next.js (13, 14, and 15), we use the remotePatterns array.
The Success Pattern:
Open your next.config.js (or next.config.mjs) and add the domains you need:
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'lh3.googleusercontent.com', // Google Profile Pictures
port: '',
pathname: '/**',
},
{
protocol: 'https',
hostname: 'images.unsplash.com',
port: '',
pathname: '/**',
},
],
},
};
export default nextConfig;
The pathname: '/**' part is critical. It tells Next.js that any image path under that hostname is allowed.
Common Mistake: Using domains (Deprecated)
Older tutorials might suggest using the domains array:
domains: ['example.com']
While this still works in some versions, it is Deprecated. It is less secure because it whitelists the entire domain without allowing you to specify protocols or sub-paths. Switch to remotePatterns for a future-proof build.
Debugging Hotlinking Protections
Sometimes Vercel isn't the problem—the External Source is.
Some platforms (like Amazon S3, Dropbox, or certain CDN providers) have Hotlinking Protection. They check the "Referer" header of the request. If the request is coming from a Vercel server instead of a user's browser, the external site might return a 403 to Vercel.
How to tell: Try opening the image URL directly in your browser.
- If it loads in your browser but not on Vercel: It's a
next.config.jsissue. - If it fails in both: The external site is blocking the request.
Fixing Permissions for Vercel Blob Storage
If you are using Vercel Blob to host your images and getting a 403, it’s usually because the token isn't being read or the file is marked as "Private."
The Fix:
- Ensure your
BLOB_READ_WRITE_TOKENis in your Vercel Environment Variables. - If you changed it, you must redeploy. For more on this, see our Vercel environment variables guide.
Image Optimization Limits: When You Hit the 403 Cap
Vercel's Hobby plan has a limit of 1,000 source images optimized per month. If you exceed this, Vercel may stop optimizing new images, resulting in 403 or 429 errors.
Pro Tip: If you have thousands of dynamic images, consider using a specialized image CDN like Cloudinary or Imgix and setting the unoptimized: true prop on the Next.js component for those specific assets.
FlowQL: Optimizing Media Delivery for High-Traffic Sites
Media delivery is the "last 20%" of performance engineering. AI assistants are great at placing an <Image /> tag on a page, but they are blind to CDN cache hit rates, remote pattern security, and bandwidth optimization.
At FlowQL, we help companies scale their media-heavy Vercel applications. We provide the senior technical oversight to audit your image optimization strategy, configure your CDNs, and ensure your "Vibe" stays fast and functional under load.
If your production site is a graveyard of broken images, it's time for an expert performance audit.
Conclusion
A 403 Forbidden error on Vercel images is a security guard doing its job. By explicitly whitelisting your external domains in next.config.js using the remotePatterns protocol, you can serve optimized images safely and reliably.
Your Action Plan:
- Check the 403 error in your browser console.
- Identify the hostname of the failing image.
- Add that hostname to
remotePatternsinnext.config.js. - Redeploy to Vercel.
Don't let a security wall hide your best assets. [Book a session with FlowQL] and let’s get your Vercel images loading perfectly today.
FAQ: Vercel Image Troubleshooting
Q: Do I need to restart my server after changing next.config.js?
A: Yes. next.config.js is only read during the server startup. You must restart npm run dev or trigger a new Vercel deployment.
Q: Can I use wildcards in hostnames?
A: Yes. You can use *.example.com in the hostname field of a remotePattern to allow all subdomains.
Q: Why do my local images work but production doesn't?
A: Locally, Next.js is often more permissive with external images to make development easier. Vercel production environments enforce the remotePatterns whitelist strictly to protect your account.
Subscribe to our blog
Get the latest guides and insights delivered to your inbox.
Join the FlowQL waitlist
Get early access to our AI search optimization platform.
Related Articles
Fixing 504 Gateway Timeout on Vercel Serverless Functions
Vercel 504 error? Learn how to fix 'Gateway Timeout' by optimizing slow database queries, handling external API latency, and managing Vercel's execution limits.
Fix: params are undefined in Next.js App Router Server Component
params undefined in your Next.js server component? Learn how to handle the async breaking change in Next.js 15 and properly await your dynamic route data.
Fix: 'NextRouter was not mounted' in Next.js App Directory
Getting the 'NextRouter was not mounted' error? Learn why next/router fails in the App Router and how to correctly use next/navigation for Next.js 14 and 15.