Diagnose common installation problems
On this page
Start with the layer that is failing: container startup, canonical origin, a product record or an external integration. Keep the first useful error and request ID; avoid gathering full credentials or customer payloads into logs.
The web service does not start
docker compose ps
docker compose logs --tail=100 db migrate web workerA stopped migration service with exit code 0 is normal. A failed migration prevents application startup. Resolve the database connection or migration failure before repeatedly restarting web.
Check that generated configuration exists and that the database initialized with the intended credentials. Changing POSTGRES_PASSWORD in a file does not reset the password inside an already initialized PostgreSQL volume.
Do not delete volumes as a generic fix. They contain the business database and local assets. Diagnose or restore from a tested backup.
Login fails behind a proxy
Compare the browser URL with BETTER_AUTH_URL: scheme, host and port must match. Check that the reverse proxy preserves Host and protocol and that the services received the changed environment after recreation.
Administration is served on the canonical origin, not an organization's custom domain. A customer domain returning no login screen can be expected routing behavior, not a missing authentication feature.
The public calculator returns 404
Open the estimator in the organization and check that a revision is published and available. Confirm the public organization slug and estimator ID. A draft-only estimator, an unpublished/archived estimator or a changed slug can make an old link unusable.
On a custom domain, also check active ownership verification, public DNS and proxy routing. Unknown hosts and cross-tenant paths are rejected. Forwarded-host values do not select organizations.
A price looks wrong
Use a known case from Moving pricing. Inspect the retained revision and ordered explanation before comparing it with the current draft.
Check rule order, percentage basis, hidden-field conditions and currency exponent. A percentage before a charge cannot modify that later charge. A hidden answer does not remain in the effective pricing inputs. A range is not another subtotal.
A visitor who opened the form before a publication can legitimately complete using the earlier pinned revision. A prior estimate should not change because a draft rate changed.
Save reports a conflict
Another editor saved a newer draft version. Preserve your intended changes, reload the current draft and reconcile them. The conflict prevents silent overwriting; repeating the same stale Save is not a resolution.
Import fails
Use a .oqs.json document within the 200 KB import limit. Check schemaVersion: "1", unknown properties, duplicate identifiers, field/rule references and formula variables.
Visibility references must point to preceding fields. Enabled contact capture needs name and email. The final graduated tier must be open-ended. These are validation rules, not cosmetic JSON formatting choices.
Exporting a newer definition to an older strict Schema reader can fail even when both say version 1. Use compatible product/package releases. Import creates a new estimator identity; it does not overwrite an existing estimator with a matching portable ID.
Logo disappears or upload is rejected
Check the supported formats and limits: decoded PNG, JPEG or WebP; at most 2 MB and 20 million pixels. An SVG renamed .png is not an accepted PNG.
For missing assets after restart, verify OQS_ASSET_DIR and volume persistence. For S3, verify the driver, bucket, endpoint, credentials and prefix shared by web and worker. Changing storage drivers does not migrate existing keys.
Email is not received
Review SMTP host, port, sender and authentication settings shared by web and worker. Port 587 requires STARTTLS; port 465 uses implicit TLS with SMTP_SECURE=true. Keep certificate verification enabled.
Check worker logs and failed-job status. System status only reports whether SMTP is configured. Confirm receipt in a controlled mailbox and inspect provider-side rejection or spam handling where available. Do not use the insecure-relay setting as a generic internet SMTP fix.
Webhooks stay pending or fail
Confirm a worker is running. During source development, run pnpm worker; Compose starts its own worker service. Inspect Settings → Webhooks for response code, attempts and error category.
A destination must resolve exclusively to public addresses and use HTTPS/443. Redirects, localhost and private IP receivers are rejected. A 401 often means the receiver is using the wrong secret or altered request bytes; other non-retryable 4xx errors need correction before manual retry.
An embedded calculator is blocked
Compare the exact parent origin with the embedding allowlist. Include www and port where applicable, and omit paths. Frame authorization is CSP-based; an iframe loading directly does not prove the parent page is allowed to frame it.
For height problems, confirm the assisted script actually loads. Plain iframes use fixed caller-controlled height. Page builders may remove scripts or move their target elements.
An API request fails
Use the error code and X-Request-Id from the response. A 403 means scope is missing; a 404 can mean the resource belongs to another organization; a 409 can mean publication or idempotency conflict. A 422 points to answers that do not match the published definition.
Honor Retry-After for 429. Keep the original idempotency key and request body when retrying a creation request. See the API walkthrough.
Share a useful bug report
Include the product release/commit, deployment method, failing operation, expected and actual behavior, safe error category and a minimal fictional reproduction. Remove API keys, secrets, session tokens and customer information. Report suspected vulnerabilities through the private reporting policy, not a public issue.