Deploying a Nuxt.js app behind Cloudflare sounded like a solid idea—great caching, global CDN, free SSL, and security features. But once I pushed my SSR build live, I was slapped with two painful problems:
- SRI Integrity Mismatch Errors
- 503 Service Unavailable on _nuxt/*.js chunks
Nothing is more frustrating than a deployment that works locally but breaks in production, especially when the browser throws cryptic integrity warnings like:
Failed to find a valid digest in the 'integrity' attribute...
So I dug deeper, reproduced the issue, figured out exactly what’s going wrong and now I’m sharing the solution so you don’t suffer like I did.
What Went Wrong in My Setup
At first, I configured nuxt-security to enforce CSP and SRI. That’s when things blew up.
The Initial Buggy Config
// nuxt.config.ts (Incorrect Example)
export default defineNuxtConfig({
modules: ['nuxt-security'],
security: {
csp: {
// WRONG: Hardcoding SHA digests causes mismatch after rebuilds
scriptSrc: [
"'self'",
"'sha384-abc123...'", // These hashes quickly go stale
],
},
sri: true // Enabled, but Cloudflare may serve cached or modified files
}
})
Resulting Problems
| Problem | Root Cause | What Happened |
|---|---|---|
| SRI Integrity Mismatch | I hardcoded CSP hashes, but Nuxt generated new ones on rebuild | Browser blocked scripts |
| 503 Errors on _nuxt/*.js | Cloudflare cached stale JS chunks | Browser returned net::ERR_ABORTED 503 |
| Preload Warnings | Preloaded assets weren’t used immediately | Chrome complained about performance |
Final Working Config
Once I understood that static SHA hashes don’t work with continuously rebuilt JS chunks, I switched to nonce-based CSP and auto-SRI handling.
// nuxt.config.ts (Correct Example with Auto-SRI & Cloudflare Safety)
export default defineNuxtConfig({
modules: ['nuxt-security'],
security: {
sri: true, // Let Nuxt auto-handle <script integrity="">
csp: {
scriptSrc: ["'self'", "'nonce-{{nonce}}'"], // Stops hash mismatch
styleSrc: ["'self'", "'unsafe-inline'"] // Needed for Tailwind in dev
}
},
nitro: {
routeRules: {
'/**': {
headers: {
'Cache-Control': 'public, max-age=0, must-revalidate' // Avoid stale Cloudflare cache
}
}
}
}
})
Bonus Improvements That Made Everything Stable
| Improvement | What I Did | Why It Helped |
|---|---|---|
| Cloudflare Cache Bypass | Added “Cache Everything: OFF” rule for /_nuxt/* | Forced fresh chunks |
| Auto Recovery From Broken Scripts | Injected JS retry handler | Prevented blank page |
| Manual Header Inspection | Ran curl -I https://example.com/_nuxt/*.js | Verified CDN source |
Auto Retry Script I Added for Safety
Even with everything fixed, I added a chunk retry safeguard to prevent script failures from causing full app crashes:
<script>
window.addEventListener('error', function (e) {
if (e.target.tagName === 'SCRIPT') {
console.warn('Chunk failed, retrying...', e.target.src)
const newScript = document.createElement('script')
newScript.src = e.target.src + '?retry=' + Date.now()
document.body.appendChild(newScript)
}
}, true)
</script>
Final Thought
I realized that most of my issues weren’t caused by Nuxt itself but by the way Cloudflare handled my assets. Integrity mismatches and 503 errors weren’t bugs in the framework, but side effects of caching and security headers working against each other. Once I let Nuxt manage SRI automatically, switched to nonce-based CSP, and told Cloudflare to stop hoarding my _nuxt files, everything clicked back into place. If you’re facing similar issues, don’t panic it’s not your code, it’s your configuration. A few intelligent tweaks can turn chaos into stability.

