systemd MemoryDenyWriteExecute is incompatible with Node V8 JIT
Running a Node.js service under systemd with the hardening directives from systemd-analyze recommendations or service-template generators.
MemoryDenyWriteExecute=yes blocks every mmap that requests both PROT_WRITE and PROT_EXEC. V8 compiles JavaScript to machine code at runtime and executes it from pages it has just written, which is exactly the access pattern the flag forbids. Node 18 fails with Fatal javascript OOM in MemoryChunk allocation failed during deserialization at startup — the V8 snapshot deserializer is the first thing that needs writable+executable pages. The error message points at memory and not at the directive, so the cause is non-obvious. The fix is to set MemoryDenyWriteExecute=no for Node service units; the other systemd hardenings — NoNewPrivileges, ProtectSystem=strict, ProtectHome=read-only, RestrictAddressFamilies, LockPersonality — still apply and provide most of the practical defense in depth. Go and Python services can keep the flag because they do not JIT.
Before copying a systemd unit template across services, audit the runtime. Anything with a JIT (Node, Java, .NET, modern Python with JIT modes, Lua under LuaJIT) needs MemoryDenyWriteExecute=no. Anything compiled or interpreted-only (Go, plain CPython, Bash) is fine with =yes.