Handling SRI Failures with onerror Handlers

Subresource Integrity (SRI) enforces cryptographic verification before script execution. When validation fails, the browser blocks execution and emits an error event. Understanding the exact trust boundary is critical for engineering resilient supply chains. Browser-enforced integrity validation executes prior to DOM parsing. onerror handlers operate outside the cryptographic verification boundary. They trigger only when hash mismatches or fetch failures bypass the integrity check. This guide details production-ready fallback architectures.

SRI Validation Failure Lifecycle & Error Propagation

The browser fetch pipeline validates the integrity attribute immediately after network response receipt. A cryptographic hash mismatch aborts parsing and prevents DOM insertion. The browser then dispatches an error event on the originating element. This event does not bubble to window.onerror by default. It requires direct element-level capture.

Cross-origin fetch behavior dictates that crossorigin="anonymous" must be present. Without it, opaque responses prevent hash computation. This triggers immediate cryptographic rejection. For baseline validation mechanics and origin isolation rules, consult Core SRI Fundamentals & Browser Security Boundaries.

DevOps teams should monitor net::ERR_INTEGRITY_CHECK_FAILED in Chrome DevTools Network tab. Firefox logs IntegrityError in the console. Both indicate cryptographic rejection. They do not indicate network timeout or DNS failure.

Inline vs Programmatic onerror Attachment Patterns

Declarative onerror attributes offer immediate binding. They complicate Content Security Policy (CSP) compliance. Inline handlers require unsafe-inline or explicit script-hash whitelisting. This violates strict CSP baselines. Programmatic attachment via addEventListener('error', handler) aligns with modern security postures.

Render-blocking scripts require careful timing. Attaching handlers post-DOMContentLoaded misses early fetch failures. Use document.createElement with synchronous property assignment for critical paths. Async loading optimization demands deferred error routing.

Cross-browser compatibility remains consistent across Chromium, Gecko, and WebKit. Event delegation on document captures failures. It loses direct element context. Direct binding preserves the failing node reference. This enables precise fallback routing.

Dynamic Fallback Injection & State Management

Fallback logic must execute synchronously within the error callback. Recursive injection risks infinite loops during persistent CDN outages. Implement global state guards using a dedicated flag. Version-pinned local mirrors guarantee deterministic recovery.

<script src="https://cdn.vendor.com/lib.js" integrity="sha384-..." crossorigin="anonymous" onerror="loadFallback(this)"></script>
<script>
function loadFallback(el) {
  if (window.__sriFallbackTriggered) return;
  window.__sriFallbackTriggered = true;
  const fb = document.createElement('script');
  fb.src = '/assets/local/lib-v2.min.js';
  document.head.appendChild(fb);
}
</script>

Programmatic loaders scale better across micro-frontends. They centralize retry logic and telemetry. Integrate Graceful Fallback Strategies for production-ready degradation paths and CDN mirror routing.

async function loadSecureAsset(url, hash, fallbackUrl) {
  const script = document.createElement('script');
  script.src = url;
  script.integrity = hash;
  script.crossOrigin = 'anonymous';
  script.onerror = () => {
    fetch('/csp-report', { method: 'POST', body: JSON.stringify({ type: 'sri-fallback', url }) });
    const fallback = document.createElement('script');
    fallback.src = fallbackUrl;
    document.head.appendChild(fallback);
  };
  document.head.appendChild(script);
}

Load-state synchronization prevents race conditions. Use Promise wrappers for async dependency chains. Ensure fallback assets match the exact API surface of the primary resource. Step-by-step resolution requires verifying the fallback hash before deployment.

CSP Alignment & Compliance Reporting

Security teams must capture SRI bypass attempts for audit trails. Configure report-uri or report-to endpoints to ingest violation payloads. Standard CSP headers block inline fallback execution unless explicitly permitted. Use strict-dynamic with nonces for dynamic script injection.

Content-Security-Policy: script-src 'self' https://cdn.vendor.com; report-uri /api/security/csp-violations

Compliance documentation requires explicit mapping of fallback assets to cryptographic guarantees. Maintain identical integrity hashes for mirrored resources. Regulatory frameworks mandate traceability for third-party dependency substitutions.

DevOps pipelines should automate hash rotation during asset updates. Integrate CSP violation logs into SIEM platforms. Correlate sri-fallback telemetry with CDN health metrics. This establishes a verifiable chain of custody for supply chain hardening.

Common Pitfalls

  • Missing state guards causing infinite fallback loops on persistent CDN failures.
  • Omitting crossorigin="anonymous" resulting in opaque responses and false-positive SRI failures.
  • Using onerror for render-blocking scripts that trigger layout shifts or FOUC.
  • Injecting fallback scripts without CSP nonce/strict-dynamic compliance.
  • Assuming onerror fires for HTTP 4xx/5xx responses without proper CORS preflight handling.
Graceful Fallback Strategies Core SRI Fundamentals & Browse…