Skip to content

Troubleshooting

This page collects common issues and how to diagnose them. Start by checking the relevant logs, then jump to the section that matches your symptom.

Where to look first

SourceCommandUse it for
Service logs (systemd)sudo journalctl -u songbird -fApp crashes, startup errors, runtime exceptions.
Docker logsdocker compose -f docker-compose.yaml logs -fSame as above, for Docker installs.
Nginx error logsudo tail -f /var/log/nginx/error.log502/504 errors, proxy and TLS problems.
Nginx access logsudo tail -f /var/log/nginx/access.logConfirm requests reach the server and their status codes.
Deploy script logcat /opt/songbird/logs/install.logFailures during install/update via songbird-deploy.

TIP

The deployment script has a built-in View Logs menu that opens all of these without typing paths.

Symptom quick reference

SymptomLikely areaJump to
Install hangs downloading packagesNetwork restrictionsInstallation stuck downloading packages
Domain won't resolve / cert failsDNS resolutionDNS resolution problems
502 Bad GatewayApp not running or wrong proxy portApp won't start / 502
Site loads but live updates stallSSE/proxy bufferingReal-time updates not arriving
Push notifications never arriveHTTPS or network/proxyPush notifications
Uploads rejected or failSize limits or diskFile uploads failing
Videos not playingffmpeg / transcodingVideo transcoding
Docker build seems stuckDependency downloadDocker build issues
TLS/certificate errorsCert paths or renewalTLS / certificate problems
Remote Channel not mirroringTelegram creds / queueRemote Channel

Installation stuck downloading packages

During installation Songbird needs to download system packages and dependencies: apt packages, Node.js (via NodeSource), npm packages, and, for Docker installs, Docker images and packages. On servers in highly restricted or filtered networks, these downloads can stall, time out, or fail outright.

Typical signs:

  • The installer or docker compose build appears frozen at a download/npm ci/apt-get install step.
  • Errors mentioning connection timeouts, TLS handshake failures, or unreachable hosts.

To work around the restriction, point the package tooling at reachable mirrors or route traffic through a proxy.

ToolWorkaround
aptUse a reachable apt mirror.
Node.js (NodeSource)Use a NodeSource mirror.
npmUse an alternate npm registry mirror.
Docker / general outboundConfigure an HTTP/HTTPS proxy for the shell or Docker daemon.

If you install with the Deployment Script, use its Configure mirrors menu to set NodeSource, apt, and npm mirrors before installing. That page also lists working mirror examples (including ones usable inside Iran's restricted environment). See Mirrors for restricted networks.

For manual or Docker installs, set a proxy in your shell before running the install commands:

bash
export HTTP_PROXY="http://your-proxy:3128"
export HTTPS_PROXY="http://your-proxy:3128"

DNS resolution problems

If your server cannot resolve domain names, package downloads, certificate issuance (Certbot/Let's Encrypt), and outbound services (push, Telegram) will all fail even when the network is otherwise reachable.

Test whether the server can resolve a domain using its current DNS configuration:

bash
# Using dig:
dig +short github.com

# Or using nslookup:
nslookup github.com

If the command returns one or more IP addresses, DNS is working. If it hangs, times out, or returns no answer / an error, the server's DNS is misconfigured or blocked.

To fix it, point the server at a working DNS resolver. On most Ubuntu servers using systemd-resolved, set the DNS= line in /etc/systemd/resolved.conf and restart the resolver:

bash
sudo nano /etc/systemd/resolved.conf
# Set, for example:
#   DNS=1.1.1.1 8.8.8.8
sudo systemctl restart systemd-resolved

Then re-test with dig +short github.com. Once DNS resolves correctly, retry the installation or the failed operation.

INFO

Choose DNS resolvers that are reachable and not blocked from your server's network. In restricted environments a public resolver may itself be filtered, in which case combine this with the mirror/proxy workarounds above.

TIP

You can use these DNS resolvers in Iran's restricted environment:

217.218.127.127
217.218.155.155

App won't start / 502 Bad Gateway

A 502 from Nginx almost always means the Node server is not reachable on the expected port.

  1. Confirm the service is running:
    bash
    sudo systemctl status songbird
    sudo journalctl -u songbird -n 100 --no-pager
  2. Confirm the proxy target matches SERVER_PORT. Nginx's proxy_pass port must equal SERVER_PORT in .env.
  3. Confirm the listen port matches CLIENT_PORT.
CheckWhereMust match
proxy_pass http://127.0.0.1:<port>Nginx site configSERVER_PORT
listen <port>Nginx site configCLIENT_PORT
client_max_body_sizeNginx site configFILE_UPLOAD_MAX_TOTAL_SIZE_MB

After any Nginx change:

bash
sudo nginx -t
sudo systemctl reload nginx

Real-time updates not arriving

Songbird uses Server-Sent Events (SSE) for live messages and presence. If messages only appear after a refresh, the SSE stream is likely being buffered by Nginx.

  • Ensure the /api/events location block is present and disables buffering (proxy_buffering off;, add_header X-Accel-Buffering no;). See Configure Nginx.
  • Confirm any upstream proxy or CDN is not buffering or timing out the connection.
  • Check proxy_read_timeout / proxy_send_timeout are long enough (the sample config uses 1h).

Push notifications not arriving

RequirementDetail
HTTPSPush requires HTTPS, except on localhost. Plain HTTP installs cannot deliver push.
VAPID keysVAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, and VAPID_SUBJECT must be set (auto-generated on first run).
iOSRequires an installed PWA on iOS 16.4+.
Network reachabilityThe server must reach push endpoints (FCM, Mozilla, Apple).

If logs show [push] delivery failed ... status=0 ... AggregateError, the server cannot reach the push services. Common causes: firewall blocking outbound HTTPS, DNS failures, or a network that requires a proxy. Configure a proxy via Push Notification Proxy and test connectivity:

bash
curl -x http://your-proxy:3128 https://fcm.googleapis.com

File uploads failing

CauseFix
Upload larger than per-file capIncrease FILE_UPLOAD_MAX_SIZE_MB.
Message total exceeds capIncrease FILE_UPLOAD_MAX_TOTAL_SIZE_MB and align Nginx client_max_body_size.
Too many files in one messageIncrease FILE_UPLOAD_MAX_FILES.
Uploads disabledSet FILE_UPLOAD=true.
Nginx rejects large bodies (413)Set client_max_body_size to match FILE_UPLOAD_MAX_TOTAL_SIZE_MB.
Disk fullCheck free space with npm run db:inspect (reports disk usage) or df -h.

After changing .env, apply the changes (see Environment Variables).

Video transcoding issues

Songbird transcodes uploaded videos to H.264/AAC MP4 when FILE_UPLOAD_TRANSCODE_VIDEOS=true, which requires ffmpeg.

  • Verify ffmpeg is installed: ffmpeg -version.
  • If videos fail to process, check the service logs for transcoding errors.
  • Set APP_DEBUG=true to get verbose [app-debug] lines covering upload/transcode events, then restart the service.

Docker build issues

If docker compose build appears stuck at RUN npm ci, it is usually downloading dependencies. Run with plain progress to see what is happening:

bash
docker compose -f docker-compose.yaml build --no-cache --progress=plain

Other checks:

  • Confirm the container is healthy: docker compose -f docker-compose.yaml ps.
  • Tail container logs: docker compose -f docker-compose.yaml logs -f.

TLS / certificate problems

SymptomCheck
Browser warns about invalid certConfirm ssl_certificate / ssl_certificate_key paths in Nginx point to valid files.
Certbot renewal failsRun sudo certbot renew --dry-run and check DNS/port 80 reachability.
IP-based cert expiredThe IP certificate flow uses short-lived (6-day) certs auto-renewed by a timer; confirm the songbird-lego-renew timer is active.
Self-signed warning (Docker default)Expected with the default self-signed cert. Replace with real certs for production.

See SSL Certificates for the full setup options.

Remote Channel not mirroring

CheckDetail
Feature enabledREMOTE_CHANNEL=true must be set on this server.
Telegram credentialsAPI ID, API hash, and session string must be configured. Run npm run remote:configure.
Channel is publicRemote Channel is locked for private channels.
History not importedOn first enable, only posts published after that point are mirrored, not history.
Queue pausedResume with npm run db:chat:edit -- <channel> --resume-queue.
Proxy neededIf the server cannot reach Telegram, set a proxy (REMOTE_CHANNEL_TELEGRAM_PROXY_URL).

See Remote Channel Setup for the complete configuration guide.


Still stuck?

If none of the above resolves the issue, gather the relevant log output and open an issue at the project repository.

Released under the MIT License.