Pterodactyl Wings Node Offline: Checks That Fix the Red Heart

Published on

Red heart on a Pterodactyl node means your browser can't reach Wings. Check the service, config.yml, DNS, SSL, ports 8080 and 2022, Cloudflare and Docker.

Disk usage and bandwidth cards in a server control panel

You open Nodes in the Pterodactyl admin area and the heart next to your node is a red outline instead of a green one that beats. The tooltip says Error connecting to node! Check browser console for details. and the server consoles on that node usually hang too, because they connect to the same address. The checks below find the cause, quickest first, with commands for Ubuntu 24.04 and Debian 12. We checked them against the source of Panel 1.15.2 and Wings 1.13.4, current on 29 October 2026.

Quick answer: Your browser draws the heart, not the panel server. The Nodes page calls https://<node FQDN>:8080/api/system (8080 by default) from your browser every 10 seconds and shows red when that fails or takes over 5 seconds. Check in this order: is Wings running (systemctl status wings, journalctl -u wings), what does wings --debug print, does /etc/pterodactyl/config.yml match the node's Configuration tab, does the FQDN resolve to the node, does Wings have a valid certificate for it when the panel uses HTTPS, are ports 8080 and 2022 open, and does Cloudflare proxy the node's record.

How the Panel Decides a Node Is Online

The admin Nodes list (index.blade.php) puts each node's address and secret token into the page. A script in your browser calls /api/system on the node with that token and waits up to 5 seconds: an answer gives a green heart with the Wings version in its tooltip, an error or silence the red outline. So:

  • The request leaves from your computer. Your DNS, network and browser rules decide whether it arrives, so a node can work for the panel server and still look offline to you.
  • An HTTPS panel needs an HTTPS node. The node form says so: "In order for browsers to connect to your node it must use a SSL connection."
  • Wings tells the browser which site may read its answers: the remote URL in config.yml (middleware.go). Open the panel on another address and the browser drops the answer.

Wings also needs the panel: at startup it fetches its server list from remote before it opens its port (root.go), so a node that cannot reach the panel never listens. The node's About page gets "Daemon Version" through the panel server. If About shows a version while the heart is red, look between your browser and the node; if About keeps spinning, start with Wings.

Read the Browser Console First

On the Nodes page, press Ctrl + Shift + J in Chrome or Cmd + Alt + I in Safari, as the troubleshooting page suggests, and find the /api/system request. The codes come from Chromium's error list, and we reproduced most of them in headless Chromium.

Chrome showsMeaningStep
net::ERR_NAME_NOT_RESOLVEDYour computer cannot resolve the FQDN5
net::ERR_CONNECTION_REFUSEDNothing listens there, or a firewall rejects it1, 7
Nothing, the request is cancelled after 5 secondsPackets are dropped7
net::ERR_CERT_DATE_INVALIDExpired certificate, or a wrong clock on your computer6, 9
net::ERR_CERT_COMMON_NAME_INVALID or net::ERR_CERT_AUTHORITY_INVALIDCertificate for another name, or self-signed6
net::ERR_SSL_PROTOCOL_ERRORHTTPS reached a port that speaks plain HTTP6, 8
Mixed Content: ... requested an insecure XMLHttpRequest endpointNode set to HTTP, panel on HTTPS6
blocked by CORS policy and not equal to the supplied originPanel opened on an address that is not remote4
net::ERR_BLOCKED_BY_CLIENTAn extension, such as an ad blocker, blocked itAllow both domains
Status 403Wings answered, but the token differs4

Step 1: Is Wings Running?

sudo systemctl status wings
sudo journalctl -u wings -n 100 --no-pager

active (running) means it is up, so go to step 4. activating (auto-restart) means it keeps crashing and systemd restarts it, per Restart=on-failure in the official unit file. failed or inactive (dead) means it stopped, and Dependency failed for Pterodactyl Wings Daemon. in the journal points at Docker (step 3). Wings also logs to /var/log/pterodactyl/wings.log.

Step 2: Run Wings in the Foreground

sudo systemctl stop wings
sudo wings --debug

Read the last lines, press Ctrl+C, then run sudo systemctl start wings. Common messages, from the Wings source:

Log lineCause
Error: Configuration File Not FoundNo /etc/pterodactyl/config.yml (step 4)
failed to load server configurationsNo server list from remote: a wrong token_id or token if it ends in You are not authorized to access this resource. (HTTP/403) (step 4), otherwise the panel is unreachable or failing
failed to configure docker environmentDocker is not running (step 3)
failed to configure HTTP server with address already in useAnother program holds the port (step 7)
failed to configure HTTPS server with no such file or directoryThe certificate files are missing (step 6)
x509: certificate has expired or is not yet validThe panel's certificate is out of date, or the node's clock is off (step 9)
x509: certificate signed by unknown authorityThe node does not trust the panel's certificate

Step 3: Check Docker

sudo systemctl status docker
sudo docker info

The Wings unit has Requires=docker.service and PartOf=docker.service. Per the systemd.unit manual, Wings will not start when Docker fails, and stopping or restarting Docker does the same to Wings. Run sudo systemctl enable --now docker, then sudo systemctl restart wings. sudo journalctl -xu docker.service shows Docker's errors; our Docker address pool post covers the network ones.

Also run systemd-detect-virt. The install guide says Wings will most likely not run on Virtuozzo, OpenVZ or LXC, and "KVM is guaranteed to work". Space-Node VPS plans are KVM with full root access, so every command here works on them.

Step 4: Compare config.yml With the Configuration Tab

Open Admin, Nodes, your node, Configuration, and compare that block with the file on the node, above all uuid, token_id, token, the api port and ssl lines, the SFTP bind_port and remote:

sudo cp /etc/pterodactyl/config.yml /etc/pterodactyl/config.yml.bak
sudo nano /etc/pterodactyl/config.yml
sudo systemctl restart wings

When you change node settings, the panel pushes them to Wings, and if Wings is unreachable it saves them anyway with the note: "You will need to manually update the configuration file (config.yml) for the daemon to apply these changes." Before Wings 1.13.3, resetting the daemon master key also broke the connection until Wings restarted.

Edit the values that differ rather than pasting over the file. Wings writes every setting, defaults included, into config.yml when it starts, so a blind paste wipes your own changes.

remote must be exactly the address you open the panel on: same https://, same hostname, no trailing slash, because Wings sends it unchanged as the allowed origin. The panel never updates it, so after a move to HTTPS or a new domain you edit it yourself. A second panel address goes under allowed_origins.

The wings configure command from the Generate Token button will not replace an existing file unless you confirm, and otherwise stops with Aborting process; a configuration file already exists for this node.

Step 5: Make Sure the FQDN Points at the Node

hostname -I
getent hosts node.example.com

Run the first on the node to see its IP addresses, the second on the panel server with your FQDN, and nslookup node.example.com on your computer. The panel server and your computer should both get the node's public IP. An address in Cloudflare's ranges means the record is proxied, because Cloudflare answers proxied records with its own anycast IPs (proxy status); see step 8.

Step 6: HTTPS Panel, HTTPS Node, Valid Certificate

"When your Panel is using SSL, the Wings must also have one created for its FQDN," says the install guide. Set Communicate Over SSL to Use SSL Connection in the node settings; a node created before the panel had HTTPS keeps its HTTP setting and causes the Mixed Content error.

The generated config expects /etc/letsencrypt/live/<fqdn>/fullchain.pem and privkey.pem, so issue the certificate for exactly that name. On a node without a web server, the Pterodactyl SSL guide uses Certbot's standalone mode, which needs port 80 free and reachable (with UFW on, run sudo ufw allow 80/tcp first):

sudo apt update && sudo apt install -y certbot
sudo certbot certonly --standalone -d node.example.com

Compare the certificate on disk with the one Wings serves:

sudo certbot certificates
openssl s_client -connect node.example.com:8080 -servername node.example.com </dev/null 2>/dev/null | openssl x509 -noout -enddate -ext subjectAltName

Different dates mean Wings still serves the old certificate. It loads the files once, at startup (through Go's ServeTLS), which is why the SSL guide says you "may also need to restart Wings". A Certbot deploy hook runs after each successful renewal and can do that for you:

sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
sudo sh -c 'printf "#!/bin/sh\nsystemctl restart wings\n" > /etc/letsencrypt/renewal-hooks/deploy/restart-wings.sh'
sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/restart-wings.sh
sudo certbot renew --dry-run
sudo /etc/letsencrypt/renewal-hooks/deploy/restart-wings.sh

The dry run tests renewal against Let's Encrypt's staging server but skips deploy hooks, so the last line runs the hook once by hand. A Wings restart leaves game servers running: the upgrade guide says they "will not be affected".

Step 7: Open Ports 8080 and 2022, Then Test From Outside

By default, Wings listens on 8080 for the panel and browsers and on 2022 for SFTP:

sudo ss -ltnp | grep wings
sudo ufw status verbose
sudo ufw allow 8080/tcp
sudo ufw allow 2022/tcp

Adjust the ports if you changed them, and check your provider's firewall too. Then test from another machine:

curl -i -m 10 https://node.example.com:8080/api/system
curl resultMeaning
401 with {"error":"The required authorization heads were not present in the request."}Wings is reachable and the certificate is fine (the typo is Wings' own); look at the browser side
curl: (6) Could not resolve hostDNS (step 5)
curl: (7) Failed to connectNothing listens, or a firewall rejects
curl: (28) Connection timed outDropped packets: a firewall or the wrong IP
curl: (35) with wrong version numberPlain HTTP on that port (steps 6, 8)
curl: (60) with certificate has expired or no alternative certificate subject name matches target host nameExpired, or issued for another name (step 6)
Client sent an HTTP request to an HTTPS server.You used http://, but Wings has SSL on

We ran these with curl 8.5 on Ubuntu 24.04.

Step 8: Cloudflare and Behind Proxy

The quick fix is a grey cloud: DNS only for the node's record. The troubleshooting page says to make sure "the orange cloud is disabled" for Wings, and Cloudflare's network ports list shows why: it proxies HTTP on 80, 8080, 8880, 2052, 2082, 2086 and 2095, and HTTPS on 443, 2053, 2083, 2087, 2096 and 8443. HTTPS to Wings on 8080 cannot pass, and 2022 is on neither list.

To keep the orange cloud, the Wings configuration page says to move the daemon port to a Cloudflare HTTPS port such as 8443 in the node settings, keep "Not Behind Proxy" with Cloudflare's Full SSL mode, and switch the orange cloud on. That page also says config.yml changes need a Wings restart, so check that its api port changed, then run sudo systemctl restart wings. It calls proxying Wings not beneficial anyway: users connect to the machine directly, so its IP stays exposed. SFTP still cannot be proxied without Enterprise, and Free and Pro plans cap proxied uploads at 100 MB (upload limits). Players reach the game ports directly either way; a Space-Node VPS includes DDoS protection.

Behind Proxy turns ssl.enabled off in the generated config (Node.php), so Wings serves plain HTTP to a proxy in front of it that handles HTTPS. Without such a proxy, you get the ERR_SSL_PROTOCOL_ERROR and wrong version number results above.

Step 9: Check the Clock

timedatectl
sudo timedatectl set-ntp true

Look for System clock synchronized: yes. Wings compares the expiry time of each console token with its own clock (parser.go), and the panel makes those tokens valid for 10 minutes, so a node clock more than 10 minutes ahead rejects all of them. Chromium also lists "Our clock is wrong" as a cause of ERR_CERT_DATE_INVALID. If set-ntp answers NTP not supported, install a time service, on Debian with sudo apt install systemd-timesyncd.

Step 10: Update Wings

The node's About page shows the running and latest version; sudo wings version prints yours. The upgrade guide updates it with:

sudo systemctl stop wings
sudo curl -L -o /usr/local/bin/wings "https://github.com/pterodactyl/wings/releases/latest/download/wings_linux_$([[ "$(uname -m)" == "x86_64" ]] && echo "amd64" || echo "arm64")"
sudo chmod u+x /usr/local/bin/wings
sudo systemctl restart wings

If the node keeps dropping offline until Wings restarts, update first. Advisory GHSA-p682-235x-522p (8 October 2026) describes an SFTP request that crashes Wings 1.13.2 and older and "takes down management of every server on the node". Wings 1.13.3 fixed it. Builds older than 1.12.0 also miss the fix for CVE-2026-21696.

If It Still Fails

sudo wings diagnostics builds a report with versions, the main Wings settings, Docker details, running containers and the last 200 log lines. You can review it, your panel's address stays out unless you include it, and it asks before uploading to ptero.co. Take it to the Pterodactyl Discord.

On the panel server, check tail -n 100 /var/www/pterodactyl/storage/logs/laravel-$(date +%F).log and run the step 7 curl test there, since that server must reach Wings too. If both share one server, the troubleshooting page suggests /etc/hosts entries that point the domains back at it. Starting over? Our Pterodactyl setup guide for resellers covers panel and Wings.

On Pelican, the Wings install guide uses the same sudo wings --debug test and SSL rule, with the config in /etc/pelican/config.yml.

FAQ

Do my game servers go down when the node shows offline? Not by themselves. They run in Docker, and Wings logs detected server is running, re-attaching to process... when it comes back. While Wings is down, you lose the console, power buttons, file manager and SFTP. If Docker stopped too, so did the servers: by default a stopping Docker daemon shuts down running containers.

Which ports does a Wings node need? 8080 for the API and 2022 for SFTP by default, every allocation port your game servers use, and port 80 while Certbot's standalone mode issues or renews a certificate.

Can I use an IP address instead of a domain? The panel allows an IP address "only if you are not using SSL for this node", and an HTTPS panel needs an HTTPS node, so once your panel runs on HTTPS, the node needs a domain. Wings has allow_cors_private_network for internal IPs without SSL, but its source says most users should not enable it.

The heart is green, but the console will not connect. Why? The console opens a websocket to the same address with a token that lasts 10 minutes, so check both clocks (step 9). Behind Cloudflare, use port 8443, which the panel suggests "to allow websocket proxying over SSL".

Sources

All opened on 29 October 2026: