Kraken.js Consul Registration Failures Causing Inter-Service 503s
Kraken.js service boots and listens locally but peers get 503/ECONNREFUSED via kraken-client. A diagnostic guide for Consul registration, health checks and nconf config drift with ordered checks and fixes.
18 Jan 2026, 02:48 UTC

The problem you can see in logs
A Kraken.js 2.x service boots, Hapi reports listening, and localhost requests succeed. Peer services calling it via kraken-client get intermittent 503, ECONNREFUSED or timeouts. Client logs show service not found or no healthy instances. The catalog shows no healthy entry, or the entry points to the wrong address.
This is almost always registration or health-check drift between what the service advertises to Consul and what Hapi actually listens on.
Cause to symptom table
| Condition | Typical symptom | Root cause |
|---|---|---|
| No catalog entry | kraken-client: service not found | serviceName/tag missing or mismatched in manifest/config; consul plugin not loaded in Kraken.js items |
| Instance critical | 503 from client, healthy locally | Health check path/method/response code misconfigured vs Hapi route; interval/timeout too aggressive |
| Wrong address/port | ECONNREFUSED or timeout, direct localhost works | nconf layer merge registers different host/port than Hapi listener |
| Client resolution failure despite healthy catalog | Stale errors after fix | Client uses wrong service name spelling/tags; catalog cache not refreshed per kraken-client behavior |
Ordered checks
1. Verify bootstrap and registration attempt
Run with verbose logging on the service host as the app user. Look for Kraken.js bootstrap completion, plugin registration for consul, and a registration attempt with service name and port.
# on service host
NODE_ENV=production node server.js 2>&1 | grep -i "consul\|register\|kraken"Expected check: a log line indicating the consul plugin loaded and a registration attempt with the service name from manifest. Risk: verbose logging increases disk I/O.
2. Inspect Consul catalog
From a host with Consul CLI access and read permissions, query the catalog.
consul catalog services | grep <service-name>
consul health service <service-name>Expected check: service name matches manifest, address and port match runtime config, tags present, health status passing. If no entry, registration never succeeded.
3. Validate health check definition vs Hapi route
Check the service manifest and effective config for health check.
{
"serviceName": "payments-api",
"port": 8000,
"consul": {
"healthCheck": "/health",
"interval": "10s"
}
}Confirm Hapi has a route for the same path and method and returns 2xx. Consul checks are declarative; changes require service restart to re-register. Consul may retain stale checks for TTL.
4. Validate nconf effective config
Kraken.js merges config via nconf layers. Print effective values for serviceName, port, host and consul address.
console.log({
serviceName: nconf.get('serviceName'),
port: nconf.get('port'),
host: nconf.get('host'),
consul: nconf.get('consul:host')
});Expected check: values match what Consul shows and what Hapi binds to. Environment variable precedence changes across Kraken.js releases.
5. Compare direct vs client resolution
From a peer service host, test direct HTTP to the registered address, then a kraken-client call using the logical service name.
curl -i http://<registered-host>:<registered-port>/healthDirect success with client failure points to name/tag mismatch or cache.
Fixes tied to findings
If no registration log: correct manifest.json serviceName and ensure the consul plugin is listed in Kraken.js items, e.g., in items.json. Restart the service to re-register.
If instance critical: fix health check URL, method and response in manifest/config so it matches the Hapi route. Adjust interval and timeout in Consul registration to allow for cold start. Restart required.
If port/host mismatch: align nconf defaults and env overrides so the registered address equals the Hapi listener. Verify host is not 127.0.0.1 when peers need to reach it.
If client cannot resolve: verify client service name spelling and required tags match the catalog entry. Clear or reload the catalog cache per kraken-client behavior; a service restart often forces refresh.
Escalation criteria
- Multiple services deregister simultaneously: suspect Consul cluster issue, network partition or ACLs.
- Health checks pass locally but Consul marks critical persistently: check network reachability, DNS and firewall between Consul server and service.
- Config changes do not propagate after restart: possible nconf layering defect or deployment artifact mismatch.
- Registration succeeds but kraken-client continues to fail after config correction: possible framework version incompatibility between client and server.
Limitations and verification
This guide assumes Kraken.js 2.x with Hapi and Consul discovery via the kraken-consul plugin. Behavior differs in kraken-node 1.x and custom discovery implementations.
Kraken.js is a legacy eBay framework with limited community support. Verify against your actual runtime.
Practical verification: start one service with verbose logging and confirm the registration log with service name and port. Query the Consul catalog for that name and inspect address, port, tags and health status. From a peer, perform a direct HTTP request to the registered address, then a kraken-client call to the same logical name, and compare results.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.