TechnitiumSoftware/DnsServer · error · FormatException

No 'healthCheck' was configured for: {appRecordName}

Error message

No 'healthCheck' was configured for: {appRecordName}

What it means

Thrown by FailoverApp CNAME.ProcessRequestAsync when the CNAME record's JSON data is missing the 'healthCheck' field. CNAME failover works the same way as address failover: it must reference a named health check to pick the alive target. A missing reference is treated as malformed configuration and raises FormatException.

Source

Thrown at Apps/FailoverApp/CNAME.cs:137

            //let Address class initialize config

            return Task.CompletedTask;
        }

        public Task<DnsDatagram?> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, DnsTransportProtocol protocol, bool isRecursionAllowed, string zoneName, string appRecordName, uint appRecordTtl, string appRecordData)
        {
            DnsQuestionRecord question = request.Question[0];

            if (!question.Name.Equals(appRecordName, StringComparison.OrdinalIgnoreCase) && !appRecordName.StartsWith('*'))
                return Task.FromResult<DnsDatagram?>(null);

            using JsonDocument jsonDocument = JsonDocument.Parse(appRecordData, Address._jsonParseOptions);
            JsonElement jsonAppRecordData = jsonDocument.RootElement;

            string? healthCheck = jsonAppRecordData.GetPropertyValue("healthCheck", null);
            if (string.IsNullOrEmpty(healthCheck))
                throw new FormatException("No 'healthCheck' was configured for: " + appRecordName);

            Uri? healthCheckUrl = null;

            if (_healthService!.HealthChecks.TryGetValue(healthCheck, out HealthCheck? hc) && ((hc.Type == HealthCheckType.Https) || (hc.Type == HealthCheckType.Http)) && (hc.Url is null))
            {
                //read health check url only for http/https type checks and only when app config does not have an url configured
                if (jsonAppRecordData.TryGetProperty("healthCheckUrl", out JsonElement jsonHealthCheckUrl) && (jsonHealthCheckUrl.ValueKind == JsonValueKind.String))
                {
                    healthCheckUrl = new Uri(jsonHealthCheckUrl.GetString()!);
                }
                else
                {
                    if (hc.Type == HealthCheckType.Https)
                        healthCheckUrl = new Uri("https://" + question.Name);
                    else
                        healthCheckUrl = new Uri("http://" + question.Name);
                }
            }

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Add a 'healthCheck' key to the CNAME record data referencing a healthCheck defined in the FailoverApp config.
  2. Verify the referenced health check id is present and correctly typed.
  3. If CNAME failover is not wanted, remove the record from the FailoverApp zone.

Example fix

// before
{ "targets": ["a.example","b.example"] }
// after
{ "healthCheck": "web", "targets": ["a.example","b.example"] }
Defensive patterns

Strategy: validation

Validate before calling

string? hc = jsonAppRecordData.GetPropertyValue("healthCheck", null);
if (string.IsNullOrEmpty(hc))
    throw new ConfigValidationException($"FailoverApp CNAME record '{appRecordName}' is missing the required 'healthCheck' field.");

Prevention

When it happens

Trigger: A CNAME-type app record under FailoverApp whose 'data' JSON has no 'healthCheck' key. Reached when a CNAME query matches the record name (or a wildcard record).

Common situations: Setting up a CNAME failover entry from scratch and forgetting the health check, or migrating an A-record failover config to CNAME and dropping the field.

Related errors


AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13). Data as JSON: /api/errors/e3ef1494f6306124. Report an issue: GitHub.