Most UserSpice install problems come down to three things: an old PHP version, the wrong file ownership/permissions for your web server, or a database that won't let you connect. This guide walks through each, plus the web-server-specific gotchas you'll hit on Apache, Nginx, and LiteSpeed.

  1. 01 PHP version

    Run a supported PHP version

    UserSpice's hard minimum is PHP 8.0.0. The current recommended floor is PHP 8.2 and the latest actively supported branch is PHP 8.4. These numbers come from the same EOL table the admin Security Dashboard uses, so this page will stay accurate as PHP releases age out.

    Currently supported branches and their official EOL dates:

    • PHP 8.2 — EOL 2026-12-31
    • PHP 8.3 — EOL 2027-12-31
    • PHP 8.4 — EOL 2028-12-31

    On shared hosting, the PHP version is almost always switchable from cPanel / Plesk / DirectAdmin under "Select PHP Version" or "MultiPHP Manager." On a VPS, install the version you want from your distro (e.g. apt install php8.3 on Debian/Ubuntu via Ondřej Surý's PPA, or dnf module enable php:remi-8.3 on RHEL/Alma/Rocky via Remi's repo) and switch the FPM pool your site uses.

  2. 02 Extensions

    Required and recommended PHP extensions

    The installer checks these for you, but knowing what they are makes it a lot easier to ask your host (or fix your own server) when something is missing.

    • pdo_mysql — required
    • mysqli — required
    • xml / simplexml — required
    • mbstring — required
    • openssl — required
    • json — required (built-in on 8.x)
    • curl — recommended (Spice Shaker, plugins)
    • zip — recommended (updates, plugins)
    • gd or imagick — recommended (avatars, image handling)
    • sodium — recommended (TOTP/Passkey crypto)
    • intl — optional

    On Debian/Ubuntu these are php8.x-mysql php8.x-xml php8.x-mbstring php8.x-curl php8.x-zip php8.x-gd. On RHEL-family they are php-mysqlnd php-xml php-mbstring php-pdo php-gd. After installing, restart PHP-FPM (or Apache, if you're using mod_php) so the new modules load.

  3. 03 chown / chmod

    File ownership and permissions on Linux

    This is the single most common reason a fresh install fails. The installer needs to write users/init.php and a few other files. If the web server user can't write to those paths, the installer just stalls or throws permission errors.

    Step 1 — figure out who your web server runs as. The user differs by distro and web server:

    • Debian / Ubuntu Apache → www-data
    • RHEL / Alma / Rocky / CentOS Apache → apache
    • Nginx (most distros) → www-data or nginx
    • OpenLiteSpeed / LiteSpeed → nobody (default) or lsadm
    • cPanel / Plesk shared host → your own user (suEXEC / PHP-FPM per-user pool)

    Confirm it with ps -ef | grep -E 'apache|nginx|httpd|lsphp|php-fpm' and look at the user column.

    Step 2 — set ownership. The cleanest pattern on a VPS is: your shell user owns the files, the web server's group owns them, and the group has write access to the bits PHP needs to write. Replace youruser and www-data with whatever applies.

    cd /var/www/yoursite
    
    # Take ownership: your user, web server's group
    sudo chown -R youruser:www-data .
    
    # Sane baseline: dirs 755, files 644
    sudo find . -type d -exec chmod 755 {} \;
    sudo find . -type f -exec chmod 644 {} \;
    
    # Make the bits PHP needs to write group-writable (2775 = setgid so new files inherit the group)
    sudo chmod 2775 users
    sudo chmod 664 users/init.php
    sudo chmod -R 2775 usersc users/images

    Step 3 — lock it back down after install. Once the installer has written users/init.php, drop it back to read-only:

    sudo chmod 644 users/init.php

    What the numbers mean: the three digits in chmod 755 are owner/group/other. 7 = read+write+execute, 5 = read+execute, 4 = read only, 6 = read+write. Never use 777 — it lets every user on the server (including any other compromised site) write to your files. 664 for files and 775 (or 2775 with setgid) for directories is almost always what you actually want.

    SELinux note (RHEL / Alma / Rocky / Fedora): if permissions look correct but Apache still can't write, SELinux is likely blocking it. Tag the writable directories with the right context: sudo chcon -R -t httpd_sys_rw_content_t users usersc and confirm with ls -Z.

  4. 04 Web servers

    Apache, Nginx, and LiteSpeed tips

    Apache

    UserSpice ships .htaccess files for friendly URLs and security. For those to do anything, Apache needs AllowOverride All on your site's directory and mod_rewrite enabled.

    # Debian / Ubuntu
    sudo a2enmod rewrite headers
    sudo systemctl restart apache2
    
    # In your vhost or apache.conf, the site's <Directory> block needs:
    <Directory /var/www/yoursite>
        AllowOverride All
        Require all granted
    </Directory>

    If you're seeing 500 errors with no log entry, it's almost always AllowOverride None hitting an .htaccess directive — Apache rejects the directive and aborts the request.

    Nginx

    Nginx ignores .htaccess entirely. You need to translate the rewrites into your server block, hand .php off to PHP-FPM, and protect the same paths the shipped .htaccess files protect.

    server {
        listen 443 ssl http2;
        server_name example.com;
        root /var/www/yoursite;
        index index.php index.html;
    
        # Friendly URLs / front-controller fallback
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
    
        # Hand .php to PHP-FPM
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        }
    
        # Block direct access to sensitive paths
        location ~* /(users/init\.php|usersc/.*\.(log|sql|env))$ { deny all; }
        location ~ /\.(?!well-known).* { deny all; }
    }

    Match the fastcgi_pass socket to the PHP-FPM version actually running (ls /run/php/ will show you). After editing, sudo nginx -t && sudo systemctl reload nginx.

    LiteSpeed / OpenLiteSpeed

    LiteSpeed reads Apache .htaccess natively, so most things "just work" — but two settings catch people out:

    • In the vhost config, set Allow Override to All (OpenLiteSpeed defaults to None).
    • Make sure the LSPHP version assigned to the vhost matches a supported branch (PHP 8.2+). On OpenLiteSpeed it's per-vhost under Script Handler.
    • If you use LiteSpeed Cache, exclude the admin area (/users/admin.php*) and any AJAX endpoints from full-page caching while you're installing — stale cached pages during install look like broken redirects.
  5. 05 Database

    Database connection issues

    The installer expects a fresh, empty MySQL or MariaDB database with a user that has full privileges on it. If the test connection fails, work through these in order:

    • 1Host: Use 127.0.0.1 instead of localhost if you hit "no such file or directory" — that error means PHP is trying a Unix socket at the wrong path. 127.0.0.1 forces TCP.
    • 2User privileges: The DB user needs ALL PRIVILEGES on the target schema during install (it creates tables, indexes, foreign keys). After install you can drop it down to SELECT, INSERT, UPDATE, DELETE if you want.
    • 3Tables already exist: If "test settings" passes but install fails partway through, your database probably already has users, groups, etc. left over from a previous attempt. Drop them or use a fresh database.
    • 4Auth plugin (MySQL 8+): If you see "The server requested authentication method unknown to the client," your DB user is using caching_sha2_password against an old PHP/mysqlnd. Either upgrade PHP or run ALTER USER 'you'@'host' IDENTIFIED WITH mysql_native_password BY 'pw';
    • 5Remote DB: If MySQL is on a different host, make sure bind-address in my.cnf isn't 127.0.0.1, the firewall allows port 3306, and the user is granted from the web server's IP ('user'@'10.0.0.5', not just 'user'@'localhost').
  6. 06 init.php

    "users/init.php is not writable"

    The installer writes your DB credentials into users/init.php. If it can't, the install can't finish. The fix is the chown/chmod work in step 03 — but if you only want a quick one-liner:

    # During install
    sudo chmod 666 users/init.php
    
    # IMMEDIATELY after install completes
    sudo chmod 644 users/init.php

    666 means anyone can write to it — fine for the 30 seconds the installer needs, not fine to leave that way. If you're on shared hosting without SSH, your control panel's File Manager or any FTP client (FileZilla, WinSCP, Cyberduck) lets you right-click → "File permissions" and type the number in.

  7. 07 Cleanup

    Cleanup step fails or won't delete files

    The installer's last step deletes the install scripts. If the web server user doesn't have write permission on the users/install directory, the cleanup quietly fails. Two options:

    • 1Give the web server group write on that one directory (chmod -R 775 users/install), click cleanup again, then remove it.
    • 2Just delete it manually: rm -rf users/install. UserSpice doesn't need any of those files at runtime.
  8. 08 Paths & redirects

    Weird redirects or "failed to open stream" errors

    If the homepage throws require_once(...): Failed to open stream right after install, the URL root saved in users/init.php doesn't match where you actually put the site. The values to check are $us_url_root (the URL path, with leading and trailing slashes — / for a domain root, /userspice/ for a subdirectory) and the absolute path constants right above it.

    Symptoms always look like an extra / or a missing one. Edit users/init.php, fix the path, save, refresh.

  9. 09 New pages

    "Illegal offset" errors on a brand-new page

    UserSpice tracks pages and their permissions in the database. A page it has never seen has no row in the pages table, which is what causes the offset errors. Fix it in one click: Admin Dashboard → Manage → Pages and let it scan the project root and /users/ folders. Newly added files get registered automatically and the errors disappear.

  10. 10 Still stuck?

    If none of the above did it

    As long as you haven't clicked the cleanup button yet, the Restart and Start Over button at the top of the installer puts everything back the way it was so you can try again with a clean slate. After that, the fastest way to get help is the community: