Skip to content

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 overrides config/auth.php.
  • A non-empty CENTRAL_DATABASE_URL, CENTRAL_LOGIN_URL, or acugis_session cookie can auto-select Central when the mode variable is absent.
  • Verify GEOSYNC_BASE_PATH and that the proxy preserves request paths.
  • Do not stack the legacy auto_prepend_file gate 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 pgsql is loaded and the sslmode is valid.
  • If omitting direct DB access, verify a candidate /api/me is reachable with the acugis_session cookie.
  • The /api/me cURL 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:

systemctl status qz-sync-backend.service
ls -l /var/run/qz-sync/.qz-sync.pipe

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 .qgs or .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 bundles PROJECTS_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.