{"record":{"id":"82d97a52b870756d","repo":"Billionmail/BillionMail","slug":"failed-to-get-all-domains-v","errorCode":null,"errorMessage":"failed to get all domains: %v","messagePattern":"failed to get all domains: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"core/internal/service/domains/domains.go","lineNumber":911,"sourceCode":"\t\t}\n\t} else {\n\t\trecords.PTR, _ = GetPTRRecord(domain, false)\n\t}\n\n\treturn\n}\n\n// RepairDKIMSigningConfig repairs the DKIM signing configuration file.\nfunc RepairDKIMSigningConfig(ctx context.Context) error {\n\tg.Log().Debug(ctx, \"Repairing DKIM signing config...\")\n\tdefer func() {\n\t\tg.Log().Debug(ctx, \"Repairing DKIM signing config completed.\")\n\t}()\n\n\t// 1. Get all domains\n\tds, err := All(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get all domains: %v\", err)\n\t}\n\n\t// 1b. Get relay-mapped domains to exclude from DKIM signing\n\trelayDomains, err := GetRelayDomains(ctx)\n\tif err != nil {\n\t\tg.Log().Warningf(ctx, \"Failed to get relay domains, signing all: %v\", err)\n\t\trelayDomains = make(map[string]bool)\n\t}\n\n\t// 2. Build the full DKIM config content\n\tvar allSignConfBlocks strings.Builder\n\tfor _, d := range ds {\n\t\t// Skip domains with active relay — relay provider signs DKIM\n\t\tif relayDomains[d.Domain] {\n\t\t\tg.Log().Debugf(ctx, \"Skipping DKIM signing for relay-mapped domain: %s\", d.Domain)\n\t\t\tcontinue\n\t\t}\n\t\t// Regenerate missing DKIM key files","sourceCodeStart":893,"sourceCodeEnd":929,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/domains/domains.go#L893-L929","documentation":"RepairDKIMSigningConfig aborts when the dao-level All(ctx) call fails to enumerate all domains, which is step 1 of the DKIM signing repair sweep. The wrapped DB error surfaces with this message to callers like SyncRelayConfigsToPostfix.","triggerScenarios":"All(ctx) returns a database error — Postgres unreachable, connection pool exhausted, table missing/corrupted, schema migration pending, query timeout, or context cancellation.","commonSituations":"Database container stopped or restarting, wrong DB credentials after a config change, migration not run after upgrade, network partition between app and Postgres, long transaction/lock blocking the domain table read.","solutions":["Verify PostgreSQL is up and reachable (docker ps, pg_isready) and fix connection settings if not","Run pending migrations and confirm the domains table exists with the expected schema","Check DB credentials in the app configuration and test the connection manually","Inspect DB logs for locks/errors, then re-run RepairDKIMSigningConfig"],"exampleFix":"// before: bare DB failure aborts repair\nds, err := All(ctx)\nif err != nil {\n    return fmt.Errorf(\"failed to get all domains: %v\", err)\n}\n// after: ensure DB is ready before repair\nif err := g.DB().Ping(ctx); err != nil {\n    return fmt.Errorf(\"database unavailable, run migrations/start postgres: %w\", err)\n}\nds, err := All(ctx)","handlingStrategy":"retry","validationCode":"if err := g.DB().Ping(ctx); err != nil {\n    return fmt.Errorf(\"postgres unreachable, start it or check credentials before repair: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"ds, err := All(ctx)\nif err != nil {\n    log.Printf(\"domain enumeration failed: %v — retrying after backoff\", err)\n    select {\n    case <-time.After(5 * time.Second):\n    case <-ctx.Done():\n        return ctx.Err()\n    }\n    return RepairDKIMSigningConfig(ctx)\n}","preventionTips":["Add DB readiness/health checks before running repair and sync jobs","Run migrations on startup so the domains schema always matches the code","Monitor Postgres connection-pool saturation to prevent query timeouts"],"tags":["database","postgresql","dkim","domain-enumeration"],"backgroundTag":"database-unavailable","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}