docs/pro/troubleshooting.md
For issues related to upgrading from GitHub Packages to public distribution, see the Upgrading Guide.
Symptom: Requests to streaming pages (or RSC payload endpoints) hang forever and never complete.
Cause: A compression middleware (Rack::Deflater, Rack::Brotli) is configured with an :if condition that calls body.each to check the response size. This destructively consumes streaming chunks from the SizedQueue, causing a deadlock.
Fix: See the Compression for Streamed RSC Responses section in the Streaming SSR guide.
Symptom: Errno::ECONNREFUSED or timeout errors when Rails tries to reach the node renderer. In tests, this often surfaces as a generic server-rendering error — the actual root cause is that the renderer was unavailable when Rails connected to REACT_RENDERER_URL, not a webpack or bundle misconfiguration.
Fixes:
curl http://127.0.0.1:3800/config.renderer_url in config/initializers/react_on_rails_pro.rb matches the renderer's actual port127.0.0.1 over localhost. RENDERER_HOST defaults to localhost, which can resolve to IPv6 (::1) or IPv4 (127.0.0.1) depending on the machine's name-resolution order; if the renderer binds to one family and Rails dials the other, the connection is refused even though the renderer is running.Procfile.web (see Heroku deployment)Symptom: Node renderer workers restart frequently or OOM. Memory grows monotonically over time.
Root cause: The Node Renderer reuses V8 VM contexts across requests. Any module-level state in your server bundle (caches, Sets, memoized functions) persists across all requests and can grow unboundedly. This is the most common cause of OOM in the Node Renderer.
Immediate mitigations:
NODE_OPTIONS=--max-old-space-size=<MB> to cap V8 heap size and force more aggressive garbage collectionallWorkersRestartInterval and delayBetweenIndividualWorkerRestarts — these periodically kill and restart workers, reclaiming all accumulated memoryInvestigation:
NODE_OPTIONS="--heapsnapshot-signal=SIGUSR2" — send kill -USR2 <worker-pid> at different times and compare in Chrome DevTools (see Debugging guide)node --inspect and Chrome DevTools (see Profiling guide)Map, Set, {} caches, and _.memoize calls — these are the most common leak sourcesconfig.ssr_pre_hook_js to run cleanup code before each render (e.g., clearing global state)Symptom: Streaming pages fail mid-stream when worker restarts are enabled.
Fix: Set gracefulWorkerRestartTimeout to a high value or disable it, so workers are not killed while serving active streaming requests.
Symptom: cached_react_component always evaluates the props block.
Fixes:
:null_store)cache_key values — if they change every request, the cache will never hitcache_key (see Caching docs)Symptom: Components show old content after deploying new JavaScript bundles.
Fix: When prerender: true is set, the server bundle digest is automatically included in the cache key. If you're not prerendering, add your bundle hash to the cache key manually, or configure dependency_globs in react_on_rails_pro.rb to bust the cache on relevant file changes.
Symptom: Rails logs a React on Rails Pro license warning or informational message on boot.
Fixes:
REACT_ON_RAILS_PRO_LICENSE environment variable is setbundle exec rake react_on_rails_pro:verify_license to check license status (use FORMAT=json for CI/CD)Symptom: The RSC payload route fails with an error.
Fixes:
config.enable_rsc_support = true in config/initializers/react_on_rails_pro.rbrsc_bundle_js_file, react_client_manifest_file, and react_server_client_manifest_file are configured and the files existSymptom: Server-rendered HTML appears but React doesn't hydrate on the client.
Fixes:
'use client' directive