Frame docs · Reference

Troubleshooting

First look at the server's own log: journalctl -u frame -n 100 with the Linux installer, or docker compose logs --tail 100 frame with Docker. systemctl status frame tells you whether it is running.

The app says it can't connect

  1. On your phone's browser, open https://your-domain/api/v1/server. You should see JSON with your server's name.
  2. If the page doesn't load:
    • DNS: does dig +short your-domain show your server's IP?
    • Firewall: sudo ufw status should allow 80 and 443. Check the provider's firewall too.
    • Service: run systemctl status frame and journalctl -u frame -n 50.
    • Tunnel: is cloudflared running (systemctl status cloudflared), and is the public hostname set to localhost:8080 (or http://frame:8080 with Docker)?
  3. In the app, type the address without https:// and without a trailing slash, such as frame.example.com. The app adds the rest.

A friend can't sign up

"Invite required" or "invite invalid": the server is invite-only. Send them a link from Invites → New invite in the admin panel, or have a member share theirs from the app. "Invalid" means the link was revoked, expired or used up (server invites are single-use by default), or that Members can invite is off and they used a member's link. Check Settings and Invites in the panel.

Lost the setup link, or locked out of the panel

Run sudo frame-admin setup-link while no admin exists. Otherwise: sudo frame-admin user reset-password <you> for a forgotten password, sudo frame-admin user reset-2fa <you> for a lost authenticator, or sudo frame-admin user promote <you> to make an existing account an admin. With Docker, use docker compose exec frame frame-server admin ….

HTTPS or certificate errors

  • With FRAME_DOMAIN, Let's Encrypt must reach ports 80 and 443 on your server directly. If the DNS record is proxied by Cloudflare (orange cloud), switch it to DNS only, or use a Cloudflare Tunnel instead.
  • Did you run sudo sh install.sh --reconfigure after setting FRAME_DOMAIN? Without it, Frame can't bind ports 80/443, and the log shows "permission denied".
  • Let's Encrypt rate limits failed attempts. If you retried many times, wait an hour.
  • The apps reject self-signed certificates. Use a real domain.

Uploads fail or videos won't send

A proxy in front is probably limiting the request size. Caddy: request_body max_size 64MB. nginx: client_max_body_size 64m. Cloudflare's free plan: 100 MB at most. Also check FRAME_MAX_UPLOAD_MB.

New messages arrive slowly behind a proxy

The proxy is buffering /api/v1/events, a Server-Sent Events stream. Turn buffering off for that path (nginx: proxy_buffering off; and proxy_read_timeout 1h;); see Behind Caddy, nginx or another proxy.

Everyone gets "too many requests"

Or rate limits hit the wrong people: Frame sees your proxy's IP instead of the visitors'. Set FRAME_TRUSTED_PROXIES to match your setup:

  • cloudflared on the same host
    cloudflare,127.0.0.1/32
  • Caddy or nginx on the same host
    127.0.0.1/32,::1/128
  • Docker with Caddy
    preset in the compose file
  • Docker with a tunnel or a host proxy
    the (b) or (d) line in docker-compose.yml

cloudflare on its own trusts nobody: it must be paired with the address the tunnel connects from.

Sign in with Apple or Google is missing

Set FRAME_PUBLIC_URL to the exact address people type into the app, then restart. If people use more than one address, list them all, separated by commas.

Notifications don't arrive

  • Check that FRAME_PUSH_RELAY isn't empty.
  • Check that the server can reach the relay: curl -sI https://frame.crow.sg/healthz.
  • On the phone, allow notifications for Frame. On Android, also turn off battery optimisation for Frame. On iOS, check Focus modes.
  • Look for push failed in the logs.

"Permission denied" or "readonly database" after admin commands

You probably ran frame-server directly as root, which left root-owned files in the data directory. Give them back to the service and restart, and from then on use sudo frame-admin …:

Terminal
sudo chown -R --reference=/var/lib/private/frame /var/lib/private/frame && sudo systemctl restart frame

Testing on your computer, an emulator or the local network

Use http://10.0.2.2:8080 in the Android emulator, http://localhost:8080 in the iOS simulator, and your computer's LAN address (such as http://192.168.1.20:8080) from a phone on the same Wi-Fi, with FRAME_LISTEN not set to 127.0.0.1. Dev mode uses port 8787. See Try it locally.

Still stuck? Ask in the GitHub repository, or write to [email protected].

For AI tools: this page as Markdown, the page index and all pages in one file.

WhatsApp