{"record":{"id":"e3ef1494f6306124","repo":"TechnitiumSoftware/DnsServer","slug":"no-healthcheck-was-configured-for-apprecordnam-e3ef14","errorCode":null,"errorMessage":"No 'healthCheck' was configured for: {appRecordName}","messagePattern":"No 'healthCheck' was configured for: (.+?)","errorType":"exception","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"Apps/FailoverApp/CNAME.cs","lineNumber":137,"sourceCode":"\n            //let Address class initialize config\n\n            return Task.CompletedTask;\n        }\n\n        public Task<DnsDatagram?> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, DnsTransportProtocol protocol, bool isRecursionAllowed, string zoneName, string appRecordName, uint appRecordTtl, string appRecordData)\n        {\n            DnsQuestionRecord question = request.Question[0];\n\n            if (!question.Name.Equals(appRecordName, StringComparison.OrdinalIgnoreCase) && !appRecordName.StartsWith('*'))\n                return Task.FromResult<DnsDatagram?>(null);\n\n            using JsonDocument jsonDocument = JsonDocument.Parse(appRecordData, Address._jsonParseOptions);\n            JsonElement jsonAppRecordData = jsonDocument.RootElement;\n\n            string? healthCheck = jsonAppRecordData.GetPropertyValue(\"healthCheck\", null);\n            if (string.IsNullOrEmpty(healthCheck))\n                throw new FormatException(\"No 'healthCheck' was configured for: \" + appRecordName);\n\n            Uri? healthCheckUrl = null;\n\n            if (_healthService!.HealthChecks.TryGetValue(healthCheck, out HealthCheck? hc) && ((hc.Type == HealthCheckType.Https) || (hc.Type == HealthCheckType.Http)) && (hc.Url is null))\n            {\n                //read health check url only for http/https type checks and only when app config does not have an url configured\n                if (jsonAppRecordData.TryGetProperty(\"healthCheckUrl\", out JsonElement jsonHealthCheckUrl) && (jsonHealthCheckUrl.ValueKind == JsonValueKind.String))\n                {\n                    healthCheckUrl = new Uri(jsonHealthCheckUrl.GetString()!);\n                }\n                else\n                {\n                    if (hc.Type == HealthCheckType.Https)\n                        healthCheckUrl = new Uri(\"https://\" + question.Name);\n                    else\n                        healthCheckUrl = new Uri(\"http://\" + question.Name);\n                }\n            }","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/Apps/FailoverApp/CNAME.cs#L119-L155","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Add a 'healthCheck' key to the CNAME record data referencing a healthCheck defined in the FailoverApp config.","Verify the referenced health check id is present and correctly typed.","If CNAME failover is not wanted, remove the record from the FailoverApp zone."],"exampleFix":"// before\n{ \"targets\": [\"a.example\",\"b.example\"] }\n// after\n{ \"healthCheck\": \"web\", \"targets\": [\"a.example\",\"b.example\"] }","handlingStrategy":"validation","validationCode":"string? hc = jsonAppRecordData.GetPropertyValue(\"healthCheck\", null);\nif (string.IsNullOrEmpty(hc))\n    throw new ConfigValidationException($\"FailoverApp CNAME record '{appRecordName}' is missing the required 'healthCheck' field.\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat CNAME failover records with the same required-field rules as A/AAAA records.","Validate all FailoverApp records (any type) for a non-empty healthCheck.","Reject half-configured records at load time."],"tags":["config","failover","cname","health-check","format-exception"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}