Most Rammerhead problems fall into a small set of categories: JavaScript rewriting failures, session or storage misconfiguration, network-level issues with WebSockets or HTTP/2, and reverse proxy setup mistakes. Use the items below to identify the root cause and apply a targeted fix.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/binary-person/rammerhead/llms.txt
Use this file to discover all available pages before exploring further.
Sites not loading or showing blank pages
Sites not loading or showing blank pages
Blank pages usually mean the JavaScript rewriting pipeline is failing or producing output that the browser rejects.Things to try:
- Open the browser console on the proxied page and look for JavaScript errors. An error referencing
hammerheador__get$points to a rewriting failure. - Disable URL shuffling for the session to rule it out as a source of confusion:
- Enable debug logging to see the full request flow:
- Set the
DEVELOPMENTenvironment variable before starting the server. This causes the proxy to serve unminifiedrammerhead.jsandhammerhead.js, making stack traces readable: - Check that
crossDomainPortis configured and reachable. Without a functioning cross-domain port, sites that issue cross-origin subrequests will silently fail.
Google login not working
Google login not working
Google login is a known limitation of Rammerhead. Google’s login flow uses advanced browser fingerprinting and security checks that detect the proxy environment and block authentication. This is not a configuration problem — it is a fundamental constraint of how Google’s authentication works.If your use case requires Google authentication, consider authenticating users directly on the origin site and exporting the resulting cookies into the session via
session.externalProxySettings or a cookie injection mechanism.High memory usage
High memory usage
Memory growth typically comes from one of two sources: the JS rewrite cache filling up in memory, or sessions accumulating in the in-memory cache.Tune the disk JS cache size or switch to memory caching:The default configuration uses Alternatively, keep disk caching but reduce the max size or item count to limit disk usage:Tune the session cache timeout:Reduce Enable
RammerheadJSFileCache (disk-backed, 5 GB limit) in src/config.js. If disk I/O is slow, switch to the in-memory cache with a size limit that fits your available RAM:cacheTimeout so inactive sessions are flushed to disk sooner:deleteUnused:Sessions created but never used (e.g., from bots probing /newsession) are kept in memory until cacheTimeout expires. With deleteUnused: true (the default), these are discarded without being written to disk.Worker crashes or ECONNRESET errors
Worker crashes or ECONNRESET errors
Connection reset errors are expected in a proxy environment — remote servers close connections abruptly for many legitimate reasons. Rammerhead handles these automatically via
addMoreErrorGuards, which is loaded at startup inside RammerheadProxy.The error guard catches ECONNRESET, EPIPE, ETIMEDOUT, ERR_INVALID_PROTOCOL, and similar codes and prevents them from crashing the worker. A process.on('uncaughtException', ...) handler acts as a last-resort failsafe for any that slip through.If you are seeing unhandled crashes (not just console noise), check:- Whether the error message includes one of the patterns above. If it does, it should have been swallowed — check your Node.js version for known issues.
- Whether you are throwing inside a pipeline handler without a try/catch. Uncaught errors in
asyncpipeline handlers propagate to the event loop. - The
wspackage version. Rammerhead requiresws@^8.2.0. A mismatched version can surface unusual WebSocket errors.
Sessions not persisting after restart
Sessions not persisting after restart
Sessions are serialized to
<saveDirectory>/<id>.rhfsession files. If sessions disappear on restart, check:- Permissions — the process user must have read and write access to
saveDirectory. deleteCorruptedSessions— if Node.js crashed during a write, the session file may be truncated JSON. WithdeleteCorruptedSessions: true, these are silently removed on next read. Set it tofalsetemporarily to see parse errors in the log.deleteUnused— sessions that were created but never used are not written to disk even once. They are only held in memory untilcacheTimeoutexpires, then discarded. This is intentional to avoid filling disk with bot-created sessions.- Stale cleanup — verify that
staleTimeoutandmaxToLiveare not set too aggressively for your use case.
Cross-domain iframes not working
Cross-domain iframes not working
Rammerhead starts two HTTP servers: one on
port and one on crossDomainPort. Hammerhead uses the second server to simulate cross-origin requests so that sites using cross-origin iframes work correctly.If cross-domain iframes break:- Make sure
crossDomainPortis notnullin yourRammerheadProxyoptions. Setting it tonullmerges both servers onto one port, which disables cross-domain simulation. - Make sure
crossDomainPortis exposed at the network level (firewall, reverse proxy, Docker port mapping). - In a reverse proxy setup, ensure
getServerInforeturns the correctcrossDomainPortas seen by the client:
Reverse proxy returning wrong URLs
Reverse proxy returning wrong URLs
When Rammerhead sits behind nginx, Caddy, or another reverse proxy, the
getServerInfo function must return the external hostname, port, and protocol — not the internal bind address. Without this, hammerhead rewrites URLs using the internal address, which the browser cannot reach.WebSocket errors
WebSocket errors
WebSocket problems usually fall into two categories: upgrade requests being rejected, and connected sockets disconnecting unexpectedly.Upgrade rejections:
- Confirm that your reverse proxy forwards the
Upgrade,Connection, andSec-WebSocket-*headers. nginx requires explicitproxy_set_header Upgrade $http_upgradeandproxy_set_header Connection "upgrade"directives. - Check that the
wspackage version is^8.2.0as specified inpackage.json. Runnpm ls wsto see what is installed.
- These are typically
ECONNRESETorEPIPEerrors from the remote server. They are caught byaddMoreErrorGuardsand should not crash the server. - As of v1.2.64, WebSocket errors are explicitly caught at the
wsserver level. Make sure you are on the latest version.
- Some sites (such as web.whatsapp.com) require an HTTP/2 connection before they accept a WebSocket upgrade. HTTP/2 is enabled by default since v1.2.64. If you disabled it (
disableHttp2: true), re-enable it for better compatibility.
Enabling verbose logging for diagnostics
Enabling verbose logging for diagnostics
Set Via the Setting
You can change the level at runtime without restarting:
logLevel to 'debug' or 'traffic' to get detailed per-request output.Via the logger constructor:DEVELOPMENT environment variable:The built-in src/config.js switches to 'debug' log level automatically when DEVELOPMENT is set:DEVELOPMENT=1 also serves unminified client-side scripts (rammerhead.js instead of rammerhead.min.js), which produces more readable stack traces in the browser.Log levels (from least to most verbose):| Level | What it shows |
|---|---|
disabled | Nothing |
error | Errors only |
warn | Errors and warnings |
info | Normal startup and lifecycle events |
traffic | Every proxied request URL and IP |
debug | Full internals including session cache operations |