Troubleshooting¶
Start with the failing layer: web/auth, metadata database, generated configuration, backend/systemd, worker dependency, target PostGIS, or optional upstream. Redact passwords, cookies, DSNs, and generated commands before sharing output.
Web and authentication¶
Redirect loop or unexpected local login¶
- Check effective
GEOSYNC_AUTH_MODE; process environment overridesconfig/auth.php. - A non-empty
CENTRAL_DATABASE_URL,CENTRAL_LOGIN_URL, oracugis_sessioncookie can auto-select Central when the mode variable is absent. - Verify
GEOSYNC_BASE_PATHand that the proxy preserves request paths. - Do not stack the legacy
auto_prepend_filegate and current Central prepend until their public paths are aligned.
Central returns 403¶
Current Central prepend requires platform admin status or a recognized admin group (administrator(s), admin(s), or dashboard-admin). Service-level non-admin permissions are implemented separately but not used by the main prepend. Confirm the session is unexpired and the user is enabled.
Central auth store unavailable (503)¶
- Validate the PostgreSQL URL and URL-encoded credentials.
- Ensure PHP
pgsqlis loaded and thesslmodeis valid. - If omitting direct DB access, verify a candidate
/api/meis reachable with theacugis_sessioncookie. - The
/api/mecURL fallback disables TLS verification; keep it local while correcting that behavior.
Legacy OIDC/social login fails¶
Replace deployment-specific issuer/client/redirect values, confirm exact callback URLs, PHP cURL, and Composer classes. Legacy social handlers contain placeholder routes and reference a missing viewer.php; they are not ready without repair. The Keycloak callback’s JWT role extraction is not signature verification.
Database and schema¶
pg_connect fails¶
Check DB_HOST, DB_NAME, DB_USER, DB_PASS, and DB_PORT; DB_SCMA does not affect the connection string. Test as the PHP service user and verify pg_hba.conf, DNS, firewall, and TLS requirements.
Table/column/type already exists¶
installer/setup.sql is for an empty database and is not idempotent. Do not rerun it. Inspect schema state and apply only numbered migrations. Back up first.
Publish or local rsync columns missing¶
Apply installer/migrations/001_publish_metadata.sql and 002_rsync_local.sql. Classes also attempt best-effort ALTER TABLE, but explicit migrations are safer and observable.
sync_secrets errors¶
No migration creates public.sync_secrets. The class is incomplete as shipped. Add reviewed DDL before enabling it and set a valid 32-byte sodium key encoded as base64; do not rotate that key without a re-encryption plan.
Backend and systemd¶
UI hangs when starting/stopping a project¶
Writing a FIFO opened with fopen(..., "a") can block when no reader is present. Check:
The path must be a FIFO with expected ownership, and PHP’s group must have write access. Restart the backend only after confirming no active operation will be disrupted.
Project status fields are blank or warnings appear¶
backend_Class parses human-readable systemctl status output and assumes keys such as active, enabled, main pid, and cpu. Locale/systemd output changes can break parsing. Inspect the raw unit status; code should eventually use systemctl show.
Unit starts then exits¶
Compare unit paths/users with /etc/default/qz-sync-backend, PHP constants, generated config, and installed scripts. Check:
journalctl -u 'qf-sync@<id>.service'
journalctl -u 'gdb-sync@<id>.service'
journalctl -u 'db-sync@<id>.service'
Also inspect /var/log/qz_sync<id>.log. Verify quartz can read project secrets and write project data.
Synchronization¶
QField authentication/download fails¶
Verify URL includes the expected API base, credentials, qfieldcloud-cli, and network access. Run list-projects as quartz with environment values supplied securely. A project must contain the configured <qf_gpkg>.gpkg.
Initial QField/ArcGIS table is not created¶
skip_init must be false. Confirm PostGIS exists, the role can create in pg_schema, and geodiff has PostgreSQL support. Worker messages contain a likely naming typo (gf_gpkg) in log text, but operations use the schema and GeoPackage inputs.
force_init lost data¶
For QField it drops the configured destination table and deletes the work directory. Restore from PostGIS/GeoPackage backup. Do not use force_init as routine retry.
No QField updates detected¶
Check the CLI list-files JSON shape and generated .meta/MD5 values. The script parses CLI output with text tools and may break across SDK output changes. Verify retention is at least 1 and disk space is available.
ArcGIS sync does nothing¶
Check AG_* credentials, ArcGIS Python API, download helper output, /tmp/<project>.zip, unzip, and ogr2ogr. The helper only proceeds when it reports a downloaded archive.
Mergin DB Sync fails¶
The unit and PHP constants expect Mergin DB Sync 2.1.1 under /home/quartz/db-sync-2.1.1, patched by installer scripts. Verify the exact installed version/patches, YAML, Python environment, and project working-directory assumptions; source uses more than one DB Sync path convention.
Rsync and files¶
Remote rsync fails¶
Inspect QZ_CONF/rsync.d/<id>.log, destination permissions, port, host, and excludes. Generated scripts use sshpass, disable strict host-key checking, and embed plaintext passwords. Prefer key-based SSH after a security redesign; never expose these scripts/logs.
Local rsync cannot attach¶
The target project must already have publisher_project_id, and a local link can attach only to that same project. Verify QGIS_PUBLISH_PROJECTS_ROOT/<publisher-id> exists and is writable. Local defaults exclude .qgs and .qgz.
Images or retained files are missing¶
Check the worker-specific directory, retention value, image target glob, and permissions. DB Sync does not support retention. “Clean” removes old project data and is not reversible.
Proxies and publishing¶
Proxy says invalid service/forbidden endpoint¶
api/proxy.php accepts only exact service, method, and path combinations. Confirm query parameters are separate from path. Add new paths only through reviewed code and tests.
Analysis is unavailable¶
PHP defaults to 127.0.0.1:9096, while the checked-in analysis service unit sets HTTP_ADDR=127.0.0.1:8081. Set ANALYSIS_UPSTREAM to the actual listener or correct the deployment unit. Check PHP cURL.
FormBuilder is unavailable¶
Verify FORMBUILDER_UPSTREAM (default port 9095), the external service, its database DSN, and GET health through the allow-listed proxy. Rotate the credential embedded in the checked-in unit.
Publish fails¶
- Ensure the source directory exists and contains
.qgsor.qgz. - Install PHP ZipArchive and cURL.
- Verify QGIS Publish
/api/geosync-publish, shared project root, timeout, and database reachability from the publisher. - First publish bundles
QZ_DATA/<GeoSync id>; republish bundlesPROJECTS_ROOT/<publisher id>. - TLS verification is disabled in the client; a remote certificate error may be hidden rather than solved. Keep the service private and fix validation.
Escalation data¶
Collect timestamps, request path/status, project ID/type, effective non-secret path/port settings, migration list, unit status, and a short redacted log window. Do not include cookies, DB_PASS, SMTP/OAuth secrets, service/PostGIS passwords, generated INI/YAML, rsync scripts, or full command lines.