Guides & Tutorials2025-12-28·5 min read

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.

#vercel#nextjs#web-performance#images#debugging

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:

  1. Downloads the image from example.com.
  2. Optimizes it.
  3. 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.js issue.
  • 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:

  1. Ensure your BLOB_READ_WRITE_TOKEN is in your Vercel Environment Variables.
  2. 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:

  1. Check the 403 error in your browser console.
  2. Identify the hostname of the failing image.
  3. Add that hostname to remotePatterns in next.config.js.
  4. 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