Skip to main content
This guide helps you solve common issues when deploying or running Primo.

Installation & Setup Issues

Setup screen doesn’t appear

Symptoms: Going to /admin redirects to sign-in instead of setup Causes:
  1. Superuser already exists (from environment variables or previous setup)
  2. Volume persisted from previous deployment
Solutions:
If you set PRIMO_SUPERUSER_EMAIL and PRIMO_SUPERUSER_PASSWORD, use those credentials for the PocketBase backend at /_/. Primo sign-in uses a separate regular account, created by setup or the PRIMO_USER_EMAIL and PRIMO_USER_PASSWORD variables. If only the superuser exists, use PocketBase to create a users record with the server Developer role.
A persistent volume keeps existing accounts after redeploying. Recover the superuser account with the command under Locked out of admin, then manage CMS users through PocketBase. Do not delete the volume to solve a sign-in problem.

Can’t access after deployment

Symptoms: Browser can’t reach your Primo instance Diagnostics:
Solutions:
  1. Test port 8080 locally on the server. For a production reverse proxy, expose ports 80 and 443 publicly and keep the backend port private.
  2. Verify port mapping in docker-compose.yml: - "127.0.0.1:8080:8080"
  3. Check if another service is using port 8080:
  1. Check DNS settings point to your server IP
  2. Wait for DNS propagation (up to 48 hours)
  3. On the server, test the backend with curl -I http://127.0.0.1:8080/admin/, then check your reverse proxy’s hostname configuration. A loopback-bound backend is not reachable through the public IP.

Runtime Issues

”No space left on device” error

Cause: Docker volume or host system out of disk space Solutions:

Database locked errors

Symptoms: Errors mentioning “database is locked” Cause: Multiple processes trying to write to SQLite simultaneously Solutions:
  1. Ensure only one Primo container is running:
  1. Restart the container:
  1. If persists, check for file permissions:

Publishing fails or times out

Symptoms: Publish button hangs or shows error Diagnostics:
Common Causes:
Check browser console for JavaScript errors. Fix any Svelte compilation errors in your blocks.
Increase Docker memory limit:
Browser publishing compiles blocks in your browser. Check browser DevTools for failed CDN or module requests and confirm that the browser can reach those URLs. The minimal Primo Docker image does not include curl; testing a CDN from inside the container would not test the browser’s connection.

Performance Issues

Slow editor loading

Causes:
  • Large blocks with heavy dependencies
  • Slow network connection
  • Server resource constraints
Solutions:
  • Remove unused dependencies
  • Split large blocks into smaller ones
  • Use lazy loading for images
Upgrade to a larger VPS or increase Railway/Fly.io resources.
Configure gzip in your reverse proxy (see Deployment Guide).
Point your domain through Cloudflare for caching and compression.

Slow published site

Diagnostics: Common Fixes:
  • Optimize images (compress, use WebP)
  • Minimize JavaScript bundle size
  • Enable caching headers in reverse proxy
  • Use a CDN

Docker Issues

Image pull fails

Error: Error response from daemon: manifest for ghcr.io/primocms/primo:latest not found Solutions:
  1. Check if you’re spelling the image name correctly
  2. Check your internet connection
  3. Try pulling manually:

Permission errors with a volume

Check the container’s effective user and the mounted directory before changing ownership:
Ensure a bind-mounted directory is writable by the effective UID/GID. The image does not declare UID 1000, so do not apply a blanket chown 1000:1000. For named volumes or hosted volumes, check the platform’s mount configuration and startup logs.

Container keeps restarting

Diagnostics:
Common Causes:
  • Application crash (check logs)
  • Port already in use
  • Out of memory
  • Volume mount issues

Authentication Issues

Can’t sign in

Symptoms: “Invalid credentials” error Checks:
  1. Verify email/password are correct
  2. Reset the password via the PocketBase admin:
  • Go to https://your-domain.com/_/
  • Sign in with superuser
  • Reset user password

Locked out of admin

Solution: To recover the PocketBase backend at /_/, create a superuser or reset an existing one’s password from the command line:
This command changes backend access. Use the backend’s users collection to reset the regular account you use for Primo sign-in.

Migration & Upgrade Issues

Data loss after an upgrade

Before updating, create a PocketBase backup and download it off-server. Verify the deployment still mounts the same persistent volume at /app/pb_data; an empty or different volume can make existing data appear lost. Follow Database backups for consistent raw backups and a tested restore procedure. Do not copy a live SQLite directory or remove the container before attempting docker cp.

Blocks not working after upgrade

Cause: Svelte version incompatibility Solution:
  1. Check release notes for breaking changes
  2. Update block code to match new Svelte version
  3. Re-publish all sites

Network & SSL Issues

SSL certificate errors

Common Causes:
Certbot should auto-renew. If not:
Ensure all assets load via HTTPS. Check:
  • Image URLs in blocks
  • External scripts in head/foot HTML
  • CSS file references
Make sure you’re using certificates from a trusted CA (Let’s Encrypt, not self-signed).

CORS errors

Symptoms: Browser console shows CORS errors Cause: Accessing Primo from a different domain than configured Solution: For normal CMS use, access the editor and API from the same origin. For an external dashboard, configure CORS_ALLOWED_ORIGINS with the exact browser origin. PRIMO_APP_URL does not control CORS.

CLI & Sync Issues

Push fails with “428 Push requires a sync baseline”

Cause: Your CLI is older than 0.2.0, and the server (3.3.0+) only accepts pushes that prove they’re based on the server’s current version. Solution: Update the CLI, then pull before pushing again:
If primo dev is running locally, stop it before updating and start it again afterwards. See Push safety.

Push refused: “changed on the server since the last sync”

Cause: Someone edited the site in the CMS (or deleted it) after your last pull. Nothing was uploaded. Solution: Save your local work, pull, re-apply your change, and push again. To replace the server’s version on purpose, use primo push --force; a backup of the server’s version is saved first. See Recover from a refused push.

Push refused: “Server does not support safe pushes”

Cause: The server is older than 3.3.0, and CLI 0.2.0 only pushes to servers that can check for conflicting edits. Solution: Upgrade the server to 3.3.0 or later (see Data loss after an upgrade for how to back up first).

primo dev says a CMS from an earlier session is still running

Cause: A previous primo dev was killed without stopping its CMS process, which still holds the port. Solution: Stop the process with the kill <pid> command from the message, or run primo dev --force. --force stops anything on the port, including another workspace’s primo dev.

primo dev starts on a different port

Cause: Port 3000 or its live-reload port (3001) is in use by another program or workspace. Solution: Nothing to fix; use the URLs primo dev prints. To choose a port, run primo dev -p 4000 or set port: in server.yaml.

A new site folder doesn’t appear in the dashboard

Cause: Folders created by hand under sites/ aren’t registered in the CMS. Solution: Stop primo dev, run primo add <folder-name> from the workspace root, then start primo dev again. primo status lists unregistered folders.

Self-hosted editor is read-only at localhost

Cause: Before 3.3.0, a production binary or Docker image opened at http://localhost showed the editor in read-only Browse mode with no Publish button. Solution: Upgrade to 3.3.0 or later.

CLI publication fails or has an unknown result

CLI publication requires primo-cli 0.2.1 or later and a CMS with the publication API. If status is unavailable, verify the server URL and site ID and update the CMS; you can use browser publishing in the meantime. For permission errors, sign in again and check your site access. If a push succeeded but publication failed, the hosted draft remains saved. Fix the reported problem and retry primo publish. If the outcome is uncertain after a connection failure, check primo status --hosted and the public site before retrying. See CLI publishing for target selection and publication states.

Getting Help

If you’re still stuck:
  1. Check the logs:
  1. Search existing issues:
  2. Ask for help:
  3. File a bug report:
    • Include: OS, Docker version, Primo version, full error logs
    • Create Issue

Next Steps

Deployment Guide

Review deployment best practices

Environment Variables

Configure Primo properly