Security Alert — May 2026 2FA Bypass CVEs
In May 2026, two critical two-factor authentication bypass vulnerabilities were disclosed in Nextcloud:
CVE-2026-45690 (CVSS score 5.9, disclosed May 15, 2026): an attacker with a username and password can bypass 2FA verification using HTTP Basic Auth (basic authentication via the Authorization: Basic base64(user:pass) header). Nextcloud, in affected versions, accepted HTTP Basic Auth even when 2FA was enabled for the targeted account.
CVE-2026-45691 (CVSS score 5.9, disclosed May 13, 2026): same vulnerability class, exploitable via a DAV Bearer token — the WebDAV protocol used by desktop sync clients (Nextcloud Desktop, Nautilus, Finder).
Both CVEs are fixed in Nextcloud 32.0.9 (branch 32) and 33.0.3 (branch 33). Branches 34.x and above are not affected. Check if your instance is vulnerable (see dedicated section below).
NC 34.0.0 — Recommended Apps Missing on First Launch
Nextcloud 34.0.0 introduces a regression in the installation wizard: recommended apps (Notes, Calendar, Contacts) are not offered during initial setup. The suggested apps list stays empty, regardless of the installation profile selected.
Practical impact: a fresh NC 34.0.0 instance lacks the basic productivity apps. Users expecting CalDAV calendar or CardDAV contact sync must install them manually from the admin interface.
Sources: GitHub issues #61313 and #61611 — fixed in 34.0.2.
Check if your apps are present:
docker compose exec -u www-data app php occ app:list | grep -E 'calendar|contacts|notes'If the command returns nothing, the apps are not installed. To add them manually:
docker compose exec -u www-data app php occ app:install calendar
docker compose exec -u www-data app php occ app:install contacts
docker compose exec -u www-data app php occ app:install notesNC 34.0.0 — Duplicated PostgreSQL Constraint and CPU Spike
On instances using PostgreSQL (instead of MariaDB/MySQL), an interrupted Nextcloud 34.0.0 migration can leave a duplicated constraint on the oc_filecache_extended table. This duplicate goes unnoticed at startup but triggers a CPU and RAM spike during the next file scan (files:scan) or automatic maintenance.
Symptoms: abnormally high CPU load on the Nextcloud container, a file scan that never completes, log errors like duplicate key value violates unique constraint.
Source: GitHub issue #61597.
Verification and fix:
docker compose exec -u www-data app php occ files:cleanup
docker compose exec -u www-data app php occ db:add-missing-indices
docker compose exec -u www-data app php occ db:add-missing-columnsIf errors persist, upgrade directly to 34.0.2 which contains the migration fix.
Prerequisites and Sizing
Recommended configuration: VPS with 2 GB RAM (4 GB for more than 5 active users), SSD required (many file and thumbnail operations), 20 GB minimum storage plus data space, Ubuntu 22.04 or Debian 12, Docker Engine ≥ 24, a domain name with TLS certificate, ports 80 and 443 open.
Installing Nextcloud with Docker Compose
Step 1 — Create the project structure
Create
/opt/nextcloud/docker-compose.ymlwith MariaDB 10.11, Redis 7-alpine, and Nextcloudnextcloud:34.0.4-apache. Bind the app to127.0.0.1:8080:80. Setdepends_on: dbandredis.Step 2 — Create the environment file
cat > /opt/nextcloud/.env << 'EOF' MYSQL_ROOT_PASSWORD=strong_root_password MYSQL_PASSWORD=strong_nextcloud_password REDIS_PASSWORD=strong_redis_password NEXTCLOUD_ADMIN_USER=admin NEXTCLOUD_ADMIN_PASSWORD=strong_admin_password NEXTCLOUD_DOMAIN=cloud.yourdomain.com EOFStep 3 — Start the containers
docker compose up -d docker compose logs -f appFirst startup takes 2 to 4 minutes. Wait for
Nextcloud was successfully installed.Step 4 — Configure Nginx with TLS
Install Nginx and Certbot, create the Nextcloud site with
client_max_body_size 10G;and proxy headers, then runcertbot --nginx -d cloud.yourdomain.com.Step 5 — Configure the trusted URL in Nextcloud
docker compose exec -u www-data app php occ config:system:set trusted_domains 0 \ --value=cloud.yourdomain.com docker compose exec -u www-data app php occ config:system:set overwrite.cli.url \ --value=https://cloud.yourdomain.com
Check if Your Instance is Vulnerable to the 2FA CVEs
Check current version:
docker compose exec -u www-data app php occ statusVulnerable versions: all Nextcloud 32.x < 32.0.9 and 33.x < 33.0.3. Branches 34.x and above are not affected by these CVEs.
Update to the patched version (branch 32 → 32.0.9, branch 33 → 33.0.3):
# Branch 32:
sed -i 's|nextcloud:[0-9.]*-apache|nextcloud:32.0.9-apache|g' docker-compose.yml
# Branch 33:
# sed -i 's|nextcloud:[0-9.]*-apache|nextcloud:33.0.3-apache|g' docker-compose.yml
docker compose pull app && docker compose up -d app
docker compose exec -u www-data app php occ upgradeOptimize Performance with Redis and OPcache
Nextcloud without Redis is a slow Nextcloud. Redis plays two critical roles: session caching (avoids disk reads/writes on every authenticated request) and distributed locking (file locking) which prevents conflicts during simultaneous synchronizations.
Verify Redis is connected:
docker compose exec -u www-data app php occ config:system:get redisIf nothing appears, add the Redis config to config.php manually.
The 5 Most Common Mistakes
1. Redis not configured — slow interface, sync conflicts.
2. overwrite.cli.url pointing to http:// — insecure share links and emails.
3. trusted_domains misconfigured — 'untrusted domain' access denied error.
4. Upload size limited to 2 MB — add client_max_body_size 10G in Nginx.
5. Missed security updates — configure update notifications and schedule regular updates.
Verify Redis Effectiveness with occ
docker compose exec -u www-data app php occ status
docker compose exec -u www-data app php occ check
docker compose exec -u www-data app php occ config:system:get redisThe occ check command lists all detected configuration issues. It is the first diagnostic to run on any existing Nextcloud instance.
Nextcloud Backups — Data, Database and Config
Nextcloud stores data in three places — all three must be backed up:
1. MariaDB database: file metadata, users, shares, installed apps.
2. nextcloud volume: PHP code, installed apps, and config/config.php.
3. User files: default in the Docker volume or in the path set by datadirectory in config.php.
# Enable maintenance mode
docker compose exec -u www-data app php occ maintenance:mode --on
# Backup the database (MariaDB 10.x)
docker compose exec -T db mysqldump -u nextcloud -p${MYSQL_PASSWORD} nextcloud | gzip > /opt/nextcloud/backups/db-$(date +%Y%m%d).sql.gz
# Disable maintenance mode
docker compose exec -u www-data app php occ maintenance:mode --offNote for MariaDB 11+: replace mysqldump with mariadb-dump (see dedicated section below).
Backup with MariaDB 11 — mariadb-dump replaces mysqldump
From MariaDB 11.0, the mysqldump and mysql binaries have been removed from the official Docker image. Only mariadb-dump and mariadb are available. Scripts still using mysqldump with a mariadb:11.x image will fail silently.
Check your MariaDB version:
docker compose exec db mariadb --versionBackup script for MariaDB 11+:
#!/bin/bash
DATE=$(date +%Y%m%d)
BACKUP_DIR=/opt/nextcloud/backups
mkdir -p $BACKUP_DIR
docker compose exec -u www-data app php occ maintenance:mode --on
# mariadb-dump replaces mysqldump on MariaDB 11+
docker compose exec -T db \
mariadb-dump -u nextcloud -p${MYSQL_PASSWORD} nextcloud \
| gzip > $BACKUP_DIR/db-$DATE.sql.gz
if gzip -t $BACKUP_DIR/db-$DATE.sql.gz 2>/dev/null; then
echo "Backup OK: $BACKUP_DIR/db-$DATE.sql.gz"
else
echo "ERROR: corrupted or empty archive"
docker compose exec -u www-data app php occ maintenance:mode --off
exit 1
fi
docker compose cp app:/var/www/html/config/config.php $BACKUP_DIR/config-$DATE.php
docker compose exec -u www-data app php occ maintenance:mode --offRestore:
gunzip -c $BACKUP_DIR/db-$DATE.sql.gz | \
docker compose exec -T db mariadb -u nextcloud -p${MYSQL_PASSWORD} nextcloudNote: if you stay on mariadb:10.11 (EOL February 2028), both mysqldump and mariadb-dump work. The removal only affects MariaDB 11.0 and above.
Next Steps — Go Further with Your Instance
Once Nextcloud is installed and secured:
Enable Talk (video conferencing): install the Nextcloud Talk app from the admin interface. For meetings with more than 4–5 participants, a TURN server is required (Coturn on a dedicated VPS).
Enable OnlyOffice or Collabora Online: these apps require their own Docker container and Nextcloud Office configuration.
Monitor your instance: configure alerts in Administration → Monitoring to receive email notifications if Nextcloud detects configuration errors, security updates, or quota issues.
Update Nextcloud in Production
Always run updates with maintenance mode enabled:
docker compose exec -u www-data app php occ maintenance:mode --on
# MariaDB 10.x:
docker compose exec -T db mysqldump -u nextcloud -p${MYSQL_PASSWORD} nextcloud \
| gzip > /opt/nextcloud/backups/pre-update-db.sql.gz
# MariaDB 11+: use mariadb-dump instead
sed -i 's|nextcloud:[0-9.]*-apache|nextcloud:34.0.4-apache|g' docker-compose.yml
docker compose pull app && docker compose up -d app
docker compose exec -u www-data app php occ upgrade
docker compose exec -u www-data app php occ maintenance:mode --offPHP 8.3: Migration and Nextcloud 35 Requirements
Nextcloud 35 makes PHP 8.3 mandatory — PHP 8.2 is no longer supported. This is documented in the official release notes and in the Nextcloud PHP compatibility matrix (GitHub wiki *Releases and PHP versions*). If you run a native installation or a Docker image locked to PHP 8.2, you must migrate PHP before upgrading to NC 35.
Check the PHP version used by your instance:
# In Docker
docker compose exec app php --version
# Native
php8.2 --version || php8.3 --versionIn Docker — the nextcloud:35.x-apache image already includes PHP 8.3+: no manual PHP migration needed. Simply update the tag:
image: nextcloud:35.0.0-apacheRequired PHP extensions for Nextcloud 35:
| Extension | Role |
|-----------|------|
| gd or imagick | Thumbnail generation |
| redis | Distributed cache and file locking |
| intl | Internationalization |
| bcmath, gmp | Cryptography |
| zip | Archive handling |
| opcache | PHP performance (required) |
Check for missing extensions:
docker compose exec -u www-data app php occ checkNextcloud 35: Upgrade Path and Supported PHP Versions
Nextcloud 35.0.0 was released on September 16, 2026 (Hub 26 Summer). It requires a strict sequential upgrade path, PHP 8.3 as minimum (PHP 8.2 is abandoned), and introduces changes for MariaDB 11 environments.
PHP 8.3 minimum — PHP 8.2 abandoned
Nextcloud 35 officially supports PHP 8.3 (minimum required), 8.4, and 8.5 (recommended). An instance running PHP 8.2 will not start after upgrading to NC 35. Always pin to an explicit Docker tag:
image: nextcloud:35.0.0-apacheMandatory sequential upgrade path: v33 → v34 → v35
# Step 1: upgrade to NC 34
docker compose exec -u www-data app php occ maintenance:mode --on
sed -i 's|nextcloud:[0-9.]*-apache|nextcloud:34.0.4-apache|g' docker-compose.yml
docker compose pull app && docker compose up -d app
docker compose exec -u www-data app php occ upgrade
docker compose exec -u www-data app php occ maintenance:mode --off
# Step 2: upgrade to NC 35
docker compose exec -u www-data app php occ maintenance:mode --on
sed -i 's|nextcloud:[0-9.]*-apache|nextcloud:35.0.0-apache|g' docker-compose.yml
docker compose pull app && docker compose up -d app
docker compose exec -u www-data app php occ upgrade
docker compose exec -u www-data app php occ maintenance:mode --offCheck the compatibility matrix at apps.nextcloud.com before each major version upgrade.
Check App Compatibility Before Upgrading to Nextcloud 35
Before upgrading to NC 35, run the built-in platform compatibility check:
docker exec -u www-data <container_name> php occ app:check-platform-compatibilityIf an app returns a compatibility error, disable it before launching the upgrade:
docker exec -u www-data <container_name> php occ app:disable app_nameAfter the upgrade, always run occ check:
docker compose exec -u www-data app php occ checkRecognize v7 — Debugging the Silent 'sh: exec: line 1' Error
The Recognize app (image and face recognition) can fail silently with:
Classifier process output: sh: exec: line 1: recognize/bin/node: not foundThis error does not appear in the admin interface — only in container logs. The app appears installed and active, but no tags are generated.
Main causes:
- CPU architecture mismatch: the Node.js binary bundled in Recognize is compiled for x86_64. On ARM64 (Raspberry Pi, ARM VPS), it is not executable.
- Missing or non-executable binary: incorrect permissions after a volume mount.
Diagnosis:
docker compose logs app | grep -i recognize
docker compose exec app sh -c "ls -la /var/www/html/apps/recognize/bin/"
docker compose exec app uname -mFix on x86_64:
docker compose exec -u www-data app php occ config:app:set recognize \
tensorflow.gpu_enabled --value=false
docker compose exec -u www-data app php occ config:app:set recognize \
node_binary --value=""
docker compose exec -u www-data app php occ recognize:classifyOn ARM64: enable WASM mode in app settings (Administration → Recognize → Use WASM backend).