Skip to main content

How-to guide

Debug connection issues

A target that will not connect blocks every collection from it. Work the problem in a fixed order — confirm what the daemon sees, turn up the logs, reproduce the failure outside Signals — then match the symptom to its cause and fix.

Work the problem in order

Most connection failures are network, credential, role, or TLS issues, and the daemon reports each with a distinct message. Before changing any configuration, gather the evidence in this order.

1. Ask the daemon what it sees

Run the built-in diagnostics against your config, then test the specific target that is failing. Use the docker exec form when the daemon runs in a container — signalsctl inherits SIGNALS_API_TOKEN inside the container and authenticates to the local API automatically.

signalsctl doctor --config signals.yaml
signalsctl connect test <target>

# or, when Signals runs in a container:
docker exec signals signalsctl doctor --config signals.yaml
docker exec signals signalsctl connect test <target>

connect test reproduces most failures on demand and prints a clear message — start there.

2. Turn up the logs

Set the daemon's log level to debug so the connection attempt, the resolved target parameters, and the failure reason are all recorded, then re-run the test.

log_level: debug

3. Reproduce with psql

Connect with psql using the same host, port, user, dbname, and sslmode as the failing target. If psql cannot connect either, the problem is outside Signals — fix networking, credentials, or TLS first.

psql "host=<host> port=<port> dbname=<dbname> \
  user=<user> sslmode=verify-full \
  sslrootcert=<path-to-ca-bundle.pem>"
Match every parameter to the target's configured values — including sslrootcert, which must point at the same CA bundle as the target's sslrootcert_file whenever sslmode is verify-full (omit it and psql cannot verify the server). A connection that succeeds with different parameters — a weaker sslmode, a superuser role — does not prove the target works.

Symptom, cause, and fix

Once you have the failure message from connect test or the debug log, find it below and apply the fix.

SymptomCause and fix
dial tcp: connect: connection refusedPostgreSQL is not running or not listening on the configured host/port, a firewall or security group is blocking the connection, or host is set to localhost while PostgreSQL is bound to a different interface. Verify connectivity with psql using the same host, port, user, and dbname; check listen_addresses in postgresql.conf and any network-level firewall rules.
DNS failure or connection timeoutNetwork path. Wrong VPC/subnet routing, the RDS security group does not allow 5432 from the Signals host, a blocking NACL, or no VPN/bastion from a laptop.
permission denied for relation pg_stat_activityThe monitoring role does not have pg_monitor membership; on RDS/Aurora it was not granted the required managed policy role. Grant it: GRANT pg_monitor TO signals;
collection blocked: role has superuser attributeThe configured user has superuser, replication, or bypassrls privileges. Create a dedicated monitoring role without those privileges: CREATE ROLE signals WITH LOGIN PASSWORD '...'; then GRANT pg_monitor TO signals; For lab/dev environments only, set SIGNALS_ALLOW_UNSAFE_ROLE=true to override.
sslmode=prefer is not allowed in prodProduction mode (env: prod) requires verify-ca or verify-full with a CA certificate. Set sslmode: verify-full and provide sslrootcert_file in your target config. For non-production environments, set SIGNALS_ALLOW_INSECURE_PG_TLS=true to allow weaker TLS modes.
TLS / certificate errorMissing or wrong CA bundle (sslrootcert_file), or a hostname mismatch — connect using the real RDS endpoint hostname, not an unmatched CNAME.
Password authentication failedSIGNALS_PRIMARY_PASSWORD not passed into the container, wrong password, or the role lacks LOGIN. See Authentication methods.
signalsctl gets HTTP 401API token mismatch — the daemon's token (SIGNALS_API_TOKEN / token_file) and the one signalsctl uses differ.
pg_stat_statements skipped / extension pg_stat_statements not availableInformational, not an error — Signals automatically skips collectors that depend on unavailable extensions. To enable it, add pg_stat_statements to shared_preload_libraries (on RDS/Aurora via a DB parameter group) and run CREATE EXTENSION pg_stat_statements; in each target database.
database is locked during collectionAnother process holds a write lock on the SQLite database file, or the filesystem does not support WAL mode. Ensure only one Signals instance writes to a given SQLite database file, and use a local filesystem that supports fcntl locking.
database or disk is fullThe store has run out of space. See Manage disk space.
Cannot find the export ZIP (Docker)It is written inside the container under /data. Bind-mount ./signals-data:/data so it appears on the host, or copy it out with docker cp.