FSIBLOG

How to Fix Nuxt.js Integrity Errors and 503 Issues Behind Cloudflare

How to Fix Nuxt.js Integrity Errors and 503 Issues Behind Cloudflare

If you have ever deployed a Nuxt.js site behind Cloudflare and watched perfectly working code suddenly break in production, you’re not alone. Two of the most common and most frustrating failure modes are Subresource Integrity (SRI) errors and 503 Service Unavailable responses. Both look like Nuxt is broken. In reality, they’re usually the result of Cloudflare features quietly mutating responses or timing out before your origin can answer.

This guide walks through what’s actually happening, why your local build runs fine while production explodes, and how to fix each issue properly without disabling security features wholesale.

Understanding the Two Errors

What is an Integrity Error?

When Nuxt builds for production, it can generate Subresource Integrity (SRI) hashes for your JavaScript and CSS files. These hashes look like this in your HTML:

<script
  src="/_nuxt/entry.abc123.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
  crossorigin="anonymous"
></script>

The browser downloads the file, hashes it, and compares it to the integrity attribute. If even one byte differs, the browser refuses to execute the script and you see an error like:

Failed to find a valid digest in the 'integrity' attribute for resource
'/_nuxt/entry.abc123.js' with computed SHA-384 integrity '…'.
The resource has been blocked.

What Does a 503 Mean Here?

A 503 Service Unavailable between Cloudflare and your origin almost always means one of three things:

  1. Your origin server didn’t respond in time (Cloudflare has a 100-second request timeout on Free/Pro plans).
  2. Your origin actively returned a 503 (overloaded, restarting, out of memory).
  3. A Cloudflare Worker or Page Rule produced an error before reaching the origin.

In Nuxt apps, 503s usually appear on SSR routes under load, on long-running API endpoints, or right after a deploy when Node hasn’t fully come up yet.

The Root Cause: Cloudflare Modifies Responses

Most Cloudflare-related Nuxt issues come down to one fact: Cloudflare can rewrite the bytes of your response. SRI hashes, however, are computed at build time and assume the response is byte-identical. When Cloudflare changes anything — even a whitespace tweak the hashes no longer match.

The most common offenders are:

Once you understand this, the fixes mostly fall into one pattern: stop Cloudflare from touching Nuxt’s built assets, and tell Cloudflare how to handle SSR vs. static routes differently.

Disable Auto Minify for Nuxt Assets

Auto Minify is the single most common cause of integrity errors. Nuxt’s Webpack/Vite output is already minified, so Cloudflare’s pass adds nothing useful it only breaks SRI.

In the Cloudflare dashboard:

  1. Go to Speed → Optimization → Content Optimization.
  2. Disable Auto Minify for JavaScript, CSS, and HTML.

If you must keep minification on for a multi-tenant zone, use a Configuration Rule to disable it only for your Nuxt build directory:

When incoming requests match: URI Path contains "/_nuxt/"
Then: Auto Minify → Off (JS, CSS, HTML)

Modern Cloudflare zones default Auto Minify to off, but older zones often have it on from years ago. Always verify.

Disable Rocket Loader (or Opt Out Per Script)

Rocket Loader rewrites your <script> tags so it can load them asynchronously. This conflicts with Nuxt’s hydration order and breaks SRI because the script tags Cloudflare serves are no longer the ones Nuxt rendered.

Recommended: Disable Rocket Loader globally under Speed → Optimization → Content Optimization.

If you need it on for marketing pages, exclude Nuxt scripts by adding data-cfasync="false". In nuxt.config.ts:

export default defineNuxtConfig({
  app: {
    head: {
      script: [
        { src: '/some-script.js', 'data-cfasync': 'false' }
      ]
    }
  }
})

For inline scripts injected by Nuxt itself, the safest option is simply to keep Rocket Loader off on the Nuxt hostname.

Turn Off Email Obfuscation on App Routes

Email Obfuscation wraps mailto: links in JavaScript decoders. On a Nuxt SSR page that contains an email anywhere in its rendered HTML, Cloudflare modifies the response and any HTML-level integrity check or hash you rely on downstream will fail.

Use a Configuration Rule:

When: Hostname equals "app.example.com"
Then: Email Obfuscation → Off

Keep it enabled on marketing pages where it’s actually useful.

Configure Caching Correctly for SSR vs. Static

A surprising number of “503 errors” come from caching the wrong things. By default, Cloudflare doesn’t cache HTML but if you’ve added an aggressive Cache Rule, you may be serving stale SSR pages or caching error responses.

The right model for Nuxt is:

PathCache strategy
/_nuxt/*Cache aggressively, immutable, 1 year
/api/*Bypass cache entirely
SSR routes (/, /posts/*)No cache, or short TTL with revalidation

Set this up under Caching → Cache Rules:

Rule 1:
  When: URI Path starts with "/_nuxt/"
  Then: Eligible for cache, Edge TTL = 1 year, override origin

Rule 2:
  When: URI Path starts with "/api/"
  Then: Bypass cache

Also, make sure your Nuxt server sets correct headers. In nuxt.config.ts:

export default defineNuxtConfig({
  routeRules: {
    '/_nuxt/**': { headers: { 'cache-control': 'public, max-age=31536000, immutable' } },
    '/api/**':   { headers: { 'cache-control': 'no-store' } },
    '/**':       { headers: { 'cache-control': 'public, max-age=0, must-revalidate' } },
  }
})

A common 503 source is Cloudflare caching a bad response from a deploy, then serving it for hours. Use Caching → Configuration → Purge Everything after deploys, or wire up a purge step into your CI.

Solve Origin Timeouts (the Real 503 Culprit)

If your SSR render takes longer than ~30–60 seconds, Cloudflare will return a 503 (or 524) before your origin responds. This often shows up only under traffic, when database calls queue up.

Diagnostics first. Check your origin logs if your Node process is responding fine but Cloudflare returns 503, the timeout is the issue. If your origin is itself returning 503, it’s an app-level problem.

Fixes:

Set the Correct SSL/TLS Mode

A miscconfigured SSL mode can cause intermittent 503s and 525/526 errors that look like Nuxt failures.

Go to SSL/TLS → Overview and set the mode to:

Also enable Always Use HTTPS and Automatic HTTPS Rewrites so mixed content doesn’t break SRI-protected scripts.

Check WAF and Rate Limiting Rules

Cloudflare’s WAF can block requests that look like attacks including legitimate Nuxt SSR requests with unusual query strings or POST bodies. When the WAF blocks a request to /_nuxt/builds/meta/*.json, hydration fails and the page appears broken even though no script error fires.

In Security → Events, filter by your domain and look for blocked requests during the time of the failure. If you see Nuxt asset paths being blocked:

  1. Find the rule ID in the event details.
  2. Create a WAF Custom Rule to skip that ruleset for your asset paths: When: URI Path starts with "/_nuxt/" or starts with "/api/_nuxt/" Then: Skip → Managed Rules

For rate limiting, exclude /_nuxt/ from any per-IP rate limits. A single user opening your site can pull dozens of chunks legitimately.

Disable SRI in Nuxt as a Last Resort

If you’ve tried everything and a Cloudflare feature you can’t disable is still mutating responses (common on shared/enterprise zones managed by another team), you can remove SRI hashes from Nuxt’s output.

Nuxt 3 / Nitro: SRI is not enabled by default in Nuxt 3. If a module added it, check that module’s config.

Nuxt 2:

// nuxt.config.js
export default {
  render: {
    crossorigin: 'anonymous'
  },
  build: {
    crossorigin: 'anonymous',
    // remove SRI
    extend(config) {
      config.output.crossOriginLoading = 'anonymous'
    }
  }
}

This is a real security tradeoff SRI exists to detect tampering so prefer fixing the Cloudflare side first. Only disable SRI when you’ve ruled out everything else.

Verification Checklist

After applying fixes, verify in this order:

  1. Hard reload the page (Cmd+Shift+R / Ctrl+Shift+F5) and watch the Network tab. Confirm /_nuxt/*.js files return 200 with cf-cache-status: HIT after the second load.
  2. Check the Console for integrity errors. They should be gone.
  3. Run curl -I https://yourdomain.com/_nuxt/entry.*.js and confirm headers include cache-control: public, max-age=31536000, immutable.
  4. Hit an SSR route under load (e.g., ab -n 200 -c 20 https://yourdomain.com/) and confirm no 503s.
  5. In Cloudflare Security → Events, confirm no Nuxt asset paths are being blocked.
Exit mobile version