
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
remoteURL inconfig.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 shows | Meaning | Step |
|---|---|---|
net::ERR_NAME_NOT_RESOLVED | Your computer cannot resolve the FQDN | 5 |
net::ERR_CONNECTION_REFUSED | Nothing listens there, or a firewall rejects it | 1, 7 |
| Nothing, the request is cancelled after 5 seconds | Packets are dropped | 7 |
net::ERR_CERT_DATE_INVALID | Expired certificate, or a wrong clock on your computer | 6, 9 |
net::ERR_CERT_COMMON_NAME_INVALID or net::ERR_CERT_AUTHORITY_INVALID | Certificate for another name, or self-signed | 6 |
net::ERR_SSL_PROTOCOL_ERROR | HTTPS reached a port that speaks plain HTTP | 6, 8 |
Mixed Content: ... requested an insecure XMLHttpRequest endpoint | Node set to HTTP, panel on HTTPS | 6 |
blocked by CORS policy and not equal to the supplied origin | Panel opened on an address that is not remote | 4 |
net::ERR_BLOCKED_BY_CLIENT | An extension, such as an ad blocker, blocked it | Allow both domains |
| Status 403 | Wings answered, but the token differs | 4 |
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 line | Cause |
|---|---|
Error: Configuration File Not Found | No /etc/pterodactyl/config.yml (step 4) |
failed to load server configurations | No 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 environment | Docker is not running (step 3) |
failed to configure HTTP server with address already in use | Another program holds the port (step 7) |
failed to configure HTTPS server with no such file or directory | The certificate files are missing (step 6) |
x509: certificate has expired or is not yet valid | The panel's certificate is out of date, or the node's clock is off (step 9) |
x509: certificate signed by unknown authority | The 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 result | Meaning |
|---|---|
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 host | DNS (step 5) |
curl: (7) Failed to connect | Nothing listens, or a firewall rejects |
curl: (28) Connection timed out | Dropped packets: a firewall or the wrong IP |
curl: (35) with wrong version number | Plain HTTP on that port (steps 6, 8) |
curl: (60) with certificate has expired or no alternative certificate subject name matches target host name | Expired, 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:
- Pterodactyl docs: Installing Wings, Wings configuration, Upgrading Wings, Troubleshooting, SSL certificates, Creating a node
- Pterodactyl Panel 1.15.2 source: Nodes list, node form, Node.php, NodeUpdateService.php, WebsocketController.php
- Wings 1.13.4 source: root.go, config.go, middleware.go, parser.go, diagnostics.go, releases, security advisories
- Pelican: Installing Wings
- Cloudflare: network ports, proxy status, upload limits, IP ranges
- Certbot: user guide, command line options
- systemd and Docker: systemd.unit, journalctl, timedatectl, Docker troubleshooting, Docker daemon logs, Docker live restore
- Tools: curl, openssl s_client, openssl x509, ss, ufw
- Chromium: net_error_list.h, CORS messages, Mixed Content messages