Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

If node -v works over SSH but your application will not start, Node.js is probably installed correctly. That command proves only that a Node executable can run in your current shell; it does not prove that the application entry point, service environment, permissions, or listening socket is correct. The reliable fix is to identify the exact binary and script, run the app directly, inspect the systemd unit and journal, then test file and network access as the service user.

What “Node.js is installed but not running” actually means

A Linux Node deployment has several independent layers. Treating them as one problem leads to wasted reinstalls and misleading tests.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Runtime: the node executable exists and can start.
  • Entry point: the JavaScript file or package command points to the application you intend to run.
  • Process configuration: the service has the required working directory, user, environment variables, and permissions.
  • Network readiness: the process stays alive and listens on the expected address and port.

node --version checks only the first item for the current shell. A service can still fail with a missing script, a module-resolution error, an absent environment variable, a permission denial, an occupied port, or an exception during startup. Work through the checks below in order; each step narrows the failure without changing unrelated parts of the server.

Start with a quick, context-aware triage

Run these commands in the same account and context where the failure occurs, then repeat the relevant checks as the systemd service user.

#1 Best Overall
Sale
Compressed Air Duster,130000RPM Super Power Cordless Air Duster,Rechargeable Brushless Blower,3 Gear Adjustable Blower with LED Light,Dust Remover for Computer/House/Outdoor/Car
  • Powerful Turbo Fan:CAGIWIRU Electric Air Duster have reached speed up to 130000RPM,Can efficient remove dust and debris.With LED light and Three Adjustable Speed to meet with different cleaning tasks.
  • With Attached USB C Fasting Charging cable.Charing 3 hours,Enjoy up to 240 minutes of use on the lowest setting, For third speed can use for 25mins.with four charging options to meet with your needs.
  • Wide Application: attached 5 different nozzles,making it suitable for a variety of scenes, such as car,pet, pc, keyboards, and other electronic devices. It also serves for office and home clean duster.
  • Handy Design & Portable:Cordless air duster electric nozzle is Light weight and small size, design and comfortable to hold and space saving, convenient to carry around. You can put it in your room or inside the car without taking up space.
  • Economical &Reusable: Built durable materials with a long-lasting battery,our CAGIWIRU air duster it's a sustainable alternative to disposable air cans.
command -v node
node --version
readlink -f "$(command -v node)"
which npm
npm --version
Observation What it establishes Next action
node --version prints a version Node can execute in this shell Verify the script and service context
command -v node returns a path This shell’s executable location is known Use that absolute path when testing systemd
Shell finds Node, systemd does not The service environment differs from your login shell Set an absolute ExecStart= and explicit variables
Direct launch prints an error The application fails before systemd is involved Fix the first application error, then retest the unit
Direct launch stays running but the unit exits The unit configuration or service permissions differ Inspect systemctl show, the journal, and the service user

1. Prove which Node binary and entry point are being used

Resolve the executable, not just its version

Shell profiles, version managers, and custom installation paths can make node resolve differently for an interactive user and for PID 1 (systemd). Record the real executable:

command -v node
node --version
readlink -f "$(command -v node)"
which npm
npm --version

If the resolved path is, for example, /usr/bin/node, use that full path in the service. Do not assume that a profile in ~/.bashrc, ~/.profile, or a version-manager initialization script is loaded when systemd starts a unit.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use an absolute application path

Change to the application directory and invoke the intended file explicitly:

cd /srv/myapp
/usr/bin/node /srv/myapp/server.js

Node resolves a non-absolute program entry point relative to the current working directory. If the file cannot be found, it throws an error. A wrong WorkingDirectory= can therefore look like a broken Node installation even when the runtime is healthy. An absolute script path removes that ambiguity.

Confirm that the entry point really exists and that the directory contains the expected package files:

ls -l /srv/myapp/server.js
ls -la /srv/myapp
find /srv/myapp -maxdepth 2 -type f ( -name package.json -o -name package-lock.json ) -print

If your application is started by an npm script, inspect package.json and test the script from the application directory. Once the script works directly, prefer its concrete Node entry point in systemd when practical; it makes the executable and arguments visible in service status output.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
EVEO® Screen Cleaner Spray Kit (Streak-Free) TV Screen Cleaner for Smart TV, Lcd, LEd, Oled | Computer Screen Cleaner Spray and Wipe Microfiber Cloth - TV, Monitor, Laptop, iPad, Car - 6.7oz 1 Pack
  • Screen Cleaner is Your Screen’s New Bestfriend! - EVEO is proud to present a screen cleaner that’s perfectly suited for your TV. Meet your new screen cleaner, computer screen cleaner, laptop cleaner, iPad cleaner, Macbook,tv cleaner or any other electronic device. Our screen cleaner spray and wipe along with the included plush microfiber cloth, easily removes dust, fingerprints & other smudges on the screen’s surface. Clean effectively for a streak-free screen
  • Gentle on your Screens - Our screen cleaner spray and wipes is compatible to be used even for the most sensitive LCD, LED, CRT, and OLED screens in proper use. Be at ease knowing that this product is compatible with all the major brands: LG, SONY, Samsung, Sharp, iPad, iPhone, Android screens, Kindle, PC monitors - we’ve got you covered! Can be used as LCD screen cleaner, tv cleaner, smart tv screen cleaner, and more
  • Premium Super Soft Plush Microfiber Cloth - Included in this efficient screen cleaning kit. This screen cleaner spray and wipe has our signature plush microfiber cloth specially designed to comply with screens and monitors and leave them streak-free. Has been shown to effectively absorbs stubborn stains, zero streaks, and no fiber shedding. Always use this together with our screen cleaner for the best results
  • Easy-to-Use Screen Cleaner Kit + microfiber cleaning cloth - The EVEO Screen Cleaning Kit will easily be your new favorite tool when it comes to taking care of the things you love most, quick and easy solution for a streak-free screen. Simply screw on the sprayer gun on the screen cleaner bottle. Spray the cleaning liquid onto the microfiber cloth, then wipe the screen until desired cleanliness & shine is achieved.
  • Quality Screen Care Kit Worth Purchasing - Enjoy a convenient Screen Cleaner anytime, anywhere you need it. Your satisfaction is our top priority. We stand behind the quality of our products and that’s why, you shouldn’t be worrying at all. We manufacture the Best Screen Cleaner. and can be used for laptop cleaning kit, laptop screen cleaner, tv screen cleaner for smart tv. MacBook screen cleaner, monitor cleaner or screen cleaner spray for electronic devices with microfiber cleaning cloth

2. Run the application outside systemd and capture the first error

A direct launch separates application defects from service-manager defects. Use the same absolute binary and script that you plan to place in ExecStart=:

cd /srv/myapp
/usr/bin/node /srv/myapp/server.js

Leave the process in the foreground while diagnosing it. Record the first error exactly rather than focusing on the final “process exited” message. Common classes have different fixes:

  • Missing entry point: correct the filename, deployment path, or working directory.
  • Module-resolution failure: install the application’s declared production dependencies in the deployed directory and check that the launch command matches the project layout.
  • Permission denial: test the same read and write operations as the service account.
  • Missing environment variable: provide the variable in the unit or an EnvironmentFile=; do not rely on a login profile.
  • Address already in use: identify the process owning the port before changing the application.
  • Initialization exception: fix the application’s configuration or startup code indicated by the stack trace.

If the process starts and remains in the foreground, stop it with Ctrl+C after testing. A successful manual launch proves that the application can run under that account and directory; it does not yet prove that the systemd unit supplies the same context.

3. Inspect systemd state and boot-time logs

Use status and the journal together

For a unit named myapp.service, run:

sudo systemctl status myapp.service --no-pager
sudo journalctl -u myapp.service -b --no-pager -n 200
sudo systemctl cat myapp.service
sudo systemctl show myapp.service -p User -p WorkingDirectory -p ExecStart -p Environment

systemctl status shows the current state, main process, recent exit information, and a short log excerpt. journalctl shows the service’s startup sequence and standard error for the current boot. The unit file and expanded properties reveal what systemd actually loaded, rather than what you intended to configure.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recognize the most useful failure indicators

Log or state Likely meaning Where to investigate
status=1/FAILURE Node started and the application exited with a failure Run the exact command manually and read the first stack trace or configuration error
203/EXEC systemd could not execute the configured program Check the absolute ExecStart= path, execute permission, and interpreter path
“No such file or directory” The binary, script, working directory, or an early dependency path is wrong Verify every path with ls and use an absolute entry point
Repeated start attempts followed by throttling The process keeps exiting and systemd limits rapid restarts Fix the first startup error, then restart after the unit is corrected
Environment value absent The service did not inherit your interactive shell’s variables Add Environment= or EnvironmentFile= and verify with systemctl show

Always inspect the current boot with -b when the symptom is “it worked before reboot.” Older boots can be queried separately, but the current boot normally contains the evidence needed to fix the active failure.

4. Make the Node.js unit explicit and reproducible

A minimal production unit should state who runs the process, where it runs, which executable starts it, and which configuration it receives. For example:

Rank #3
Sale
BladeHawks RGB Gaming Mouse Pad Extra Large Extended 31.5x12 Inch-Black | LED mouse pad with 14 lighting modes, covers keyboard & mouse, anti-slip rubber base, waterproof surface, USB powered
  • 【Large size】:Measuring 800 x 300 mm/ 31. 5×12 inches, which is wider and taller than others. Large mouse pad can perfectly fit your keyboard and mouse of any size, and there is also ample space for peripherals such as phones, tablets, etc.
  • 【LED backlight mouse pad】:Blade Hawks RGB mouse pad provides 7 static modes and 7 dynamic modes will give you the options you are looking for. Power-off memory function remembers the last lighting mode you selected. The super glow fiber Chroma will give you a colorful gaming setup that you want.
  • 【Anti-slip rubber base】:Made from Natural rubber, this gaming mousepad will firmly grip your desktop, allowing you to enjoy the ultimate precision in the games you are most passionate about. It also comes with a texture that enhances this ability even further.
  • 【Smooth and waterproof surface】: Micro-textured cloth surface, for extremely precise mouse control and a smooth movement. When liquid splashes on the gaming mouse pad, it forms water droplets and slides down. Will not delay your work or gameplay.
  • 【Plug and play】: This mouse and keyboard pad is powered by USB, plug and play, no driver required. One button control light modes. Press one time to change the lighting mode, press twice to change the brightness, press and hold about 3 seconds turn ON/OFF.
[Unit]
Description=My Node.js application
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=myapp
WorkingDirectory=/srv/myapp
ExecStart=/usr/bin/node /srv/myapp/server.js
Restart=on-failure
Environment=NODE_ENV=production
# EnvironmentFile=/etc/myapp/myapp.env

[Install]
WantedBy=multi-user.target

Why each setting matters

  • User=myapp prevents the application from requiring root privileges and makes permission failures reproducible.
  • WorkingDirectory=/srv/myapp controls how relative file paths are resolved.
  • ExecStart=/usr/bin/node /srv/myapp/server.js avoids PATH and relative-entry-point surprises.
  • Restart=on-failure retries unexpected exits but does not hide a clean, intentional stop.
  • Environment= and EnvironmentFile= put required configuration in the service definition rather than an interactive profile.
  • After=network-online.target and Wants=network-online.target express the unit’s network-start ordering; they do not repair an application that binds to the wrong address or port.

Keep secrets in a root-readable environment file with appropriate permissions instead of embedding them in a broadly readable unit. Verify what systemd loaded:

sudo systemctl show myapp.service -p ExecStart -p Environment

Give the service private writable directories

Do not make the entire application tree writable just because the app needs a cache, upload directory, socket, or runtime file. systemd provides StateDirectory= for persistent private service state and RuntimeDirectory= for runtime data that belongs under the service’s managed directories. Add them under [Service] when your application needs them:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
StateDirectory=myapp
RuntimeDirectory=myapp

Adjust the application configuration to use those paths, or create narrowly scoped directories owned by myapp. This keeps code and dependencies read-only while giving the process only the write access it needs.

Reload, enable, and test the corrected unit

sudo systemctl daemon-reload
sudo systemctl enable --now myapp.service
sudo systemctl restart myapp.service
sudo systemctl status myapp.service --no-pager

daemon-reload makes systemd reread a changed unit. enable --now both registers the unit for the normal boot target and starts it immediately. After any change, inspect the journal again instead of assuming a successful command means a healthy application.

5. Test files and commands as the service user

A command that succeeds as your SSH account can fail for myapp. Test the exact executable, entry point, and directory traversal under the configured account:

sudo -u myapp test -r /srv/myapp/server.js
sudo -u myapp /usr/bin/node --version
namei -l /srv/myapp/server.js

namei -l displays permissions for every directory component, which helps find a parent directory that blocks traversal even when the file itself is readable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Vaydeer Wrist Rest for Keyboard and Mouse, Computer Ergonomic Wrist Support Pad, Soft Memory Foam Arm Cushion for Desk, Palm Hand Office Laptop Typing
  • 【Softer and More Comfortable】Vaydeer wrist rest has unique diamond pattern, which is the combination of softness and aesthetics. The materials of wrist rest are improved into higher quality memory foam and covered with silky smooth lycra. The computer wrist rest makes you as comfortable and cushiony as like rest your wrists on clouds.
  • 【Ergonomic Wrist Saver】The wrist rests for keyboard and mouse comes with a 17.32×3.15×0.83 inch keyboard wrist pad and a 5.94×3.15×0.83 inch mouse wrist support. Based on ergonomic design, the unique concave shape is the perfect fit for your wrist joints. The wrist rest pad fits most computer keyboards and laptops, improve hand and wrist posture, release your wrist and arm stress.
  • 【Non-Slip Rubber Bottom】Featuring an anti-skid silicone base on the bottom, this wrist keyboard support stays firmly in place on your desk, preventing the padding from sliding around, ensuring stable and consistent wrist support during extended computer sessions.
  • 【Better Experience & Pain Relief】Our keyboard arm rest is beneficial to alleviate the soreness caused by direct contact and friction between your arm and a hard desk surface, reducing the risk of wrist fatigue or carpal tunnel. The soft texture of memory foam can evenly distribute the pressure around your wrists and provide good support with just enough give.
  • 【Helpful in Multiple Scenarios】Whether you're working, studying, writing, typing, gaming, this keyboard and mouse rest combo is an essential accessory to add comfort and support to your hands and wrists. It’s also a great gift for men, women, family, friend, coworker, gamer, teacher, etc.

Repeat the checks for every path the application writes: uploads, caches, generated files, Unix sockets, logs, and state directories. A service can read its JavaScript but exit when it tries to create a session file or migration lock. Correct ownership and directory modes narrowly; avoid chmod -R 777, which grants unnecessary access and can conceal the real ownership mistake.

If the application is deployed from a user’s home directory, verify permissions on the home and parent directories as well. Moving production code to a dedicated path such as /srv/myapp often makes ownership and traversal rules easier to reason about, but the decisive test is whether the configured service user can perform each required operation.

6. Confirm that Node is listening on the expected socket

Find the owner of the port

sudo ss -ltnp
sudo ss -ltnp '( sport = :3000 )'

Replace 3000 with the port configured for your application. If another process owns it, stop or reconfigure that process only after identifying why it is there. If no listener appears, the application may have exited, may be listening on a different port, or may bind only after a failing initialization step.

Test locally before a proxy, firewall, or DNS

curl -v http://127.0.0.1:3000/

A successful local response proves that a process is reachable on that address and port from the server itself. It does not prove that external traffic is routed correctly. If local curl fails, continue with Node and systemd diagnostics rather than changing DNS or firewall rules.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Pay attention to the bind address:

  • 127.0.0.1 accepts local connections only. A reverse proxy on the same host can reach it, but direct external clients cannot.
  • An address or port different from the proxy configuration produces connection failures even when Node is healthy.
  • Changing the bind address or port requires changing the application environment or unit consistently, followed by a restart and a new ss and curl check.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

7. Check Node’s permission model only when it is enabled

Recent Node deployments may enable the permission model with the --permission command-line option or through NODE_OPTIONS. Do not troubleshoot this feature unless the unit or launch scripts actually contain it.

Find permission flags in the service and application

grep -R --line-number -- '--permission|NODE_OPTIONS' /etc/systemd/system /srv/myapp 2>/dev/null

With enforcement enabled, operations outside the granted policy can fail with ERR_ACCESS_DENIED. The denied categories can include filesystem reads or writes, network access, child processes, workers, native add-ons, WASI, FFI, and the inspector. A service may therefore pass a basic version check and still fail during initialization when it reads configuration or opens a socket.

Best Value
Sale
Under Desk Cable Management Tray No Drill, Metal Mesh Cable Management Under Desk with Clamp Mount, 2 Hole Cable Tray with Wire Management and Cord Organizer for Home Office Standing Desk
  • 【No Drill Mounted】Cable management tray can be assembled in as little as 3 minutes or less-simply. Side clips easily clampe the edge of desk, pass through the holes on the sides, and secure excess cables with baskets. Desk cable management supports inward or outward installation to meet your needs in different scenarios, and provides you with great convenience when collecting and organizing wires.
  • 【Rubber Pad Protects Desk】Wire organizer under desk built-in soft rubber pads on the clamp protect your desk from scratches, so you will not damage your furniture or office.
  • 【Sturdy and Beautiful】Cord management under desk is made of high-quality carbon steel and holds about 15 lbs. The wire basket has 2 holes on each side of the tray to enable your cables to pass freely. Cable baskets are suitable for desk thickness use from 0.4" to 2.4".
  • 【Space Saving & Keep Organized】Desk cable management tray holds all your power cords, outlet strips, USB hubs and computer transformers hidden from your feet, and the data cables will not enter the vacuum cleaner to keep your desk clean and tidy. Desk wire organizer is also suitable for use in the kitchen and outdoors.
  • 【Reduce Safety Risks】Cable tray under desk keeps all plugs away from your kids, no more worry about tripping. Using 2 holes wire tray saves extra space, helps you easily cabling and wire protection. The mesh design is not easy to accumulate dust, but avoids safety accidents caused by messy wires.

Audit before enforcing a tighter policy

Node provides permission-audit mode, which records violations while allowing the operation to continue. Use it to identify the application’s actual requirements, then replace broad allowances with the smallest set that supports the workload. For example, a policy might need a filesystem read allowance for /srv/myapp and network access:

/usr/bin/node --allow-fs-read=/srv/myapp --allow-net /srv/myapp/server.js

Only add categories and paths that the application demonstrably needs. After changing flags, inspect the journal for any remaining access errors and confirm that the service still starts after a clean restart.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why Node works over SSH but fails after reboot

This symptom almost always indicates a context difference rather than a damaged runtime. During SSH, your shell may load a PATH modification, a version-manager script, exported secrets, or a working directory that systemd never sees. At boot, systemd starts the unit with the declared user, paths, and environment.

  1. Run command -v node in the shell where the app works.
  2. Put the returned absolute path in ExecStart=.
  3. Set WorkingDirectory= and an absolute script path.
  4. Move required variables into Environment= or EnvironmentFile=.
  5. Verify the effective values with systemctl show myapp.service -p User -p WorkingDirectory -p ExecStart -p Environment.
  6. Test the executable and file access as the configured user with sudo -u myapp.
  7. Enable the unit, reboot if necessary, and inspect journalctl -u myapp.service -b for the current boot.

Do not “fix” this by adding profile-sourcing commands to random startup files. A self-contained unit is easier to audit, reproduce, and recover.

Choose a startup method deliberately

For one Linux server, systemd is usually the clearest baseline because it exposes unit state, exit codes, boot ordering, logs, and restart behavior through standard commands. A shell launch or separate process manager can work, but it changes where startup authority and failure evidence live.

Axis systemd unit Shell or other process manager
Startup authority Managed by the operating system and boot targets Depends on a shell session, wrapper, or separate manager
Environment reproducibility Variables and paths can be declared explicitly Often depends on profile files or manager-specific configuration
Failure visibility systemctl status and the journal expose state and stderr Evidence may be split among terminal output, wrapper logs, and manager commands
Restart behavior Configured with directives such as Restart=on-failure Controlled by the shell script or manager’s own policy
Boot recovery enable ties startup to the normal boot target Requires a separate boot integration mechanism

The choice does not remove the need to verify the binary, entry point, permissions, and listener. It only determines which component owns startup and where you inspect its failures.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A compact failure-to-fix decision path

  • Version command fails: repair the Node installation or PATH for the account being tested; do not debug systemd yet.
  • Version works but the direct script fails: fix the application path, dependencies, configuration, permissions, or startup exception.
  • Direct script works but systemd reports 203/EXEC: correct the executable path and execute permissions in ExecStart=.
  • Systemd reports status=1/FAILURE: compare the unit’s user, directory, command, and environment with the successful manual launch; read the first journal error.
  • Unit is active but no port is listening: inspect the application’s configured port, startup logs, and whether it exits after reporting “active.”
  • Port is listening but local curl fails: verify the address, port, protocol, and application route.
  • Local curl works but external access fails: investigate the reverse proxy, firewall, or DNS only after the local listener is confirmed.
  • ERR_ACCESS_DENIED appears: inspect --permission, NODE_OPTIONS, and audit output, then grant only the required capability.

Final verification checklist

  • command -v node and readlink -f identify the binary used by the deployment.
  • The absolute entry point exists and launches successfully from the declared working directory.
  • User=, WorkingDirectory=, ExecStart=, and required environment values are explicit in the unit.
  • The service user can read application files and write only the required state and runtime directories.
  • systemctl status shows the unit active without a restart loop, and the journal contains no unresolved startup error.
  • ss -ltnp shows the expected listener, and curl http://127.0.0.1:PORT/ reaches it locally.
  • If the permission model is enabled, every denied operation has a justified allow flag and the service survives a restart.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.