{"record":{"id":"ac6c9e8585d387e9","repo":"hashicorp/nomad","slug":"check-q-is-duplicate","errorCode":null,"errorMessage":"check %q is duplicate","messagePattern":"check %q is duplicate","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":8522,"sourceCode":"\t\t\t\tif err != nil {\n\t\t\t\t\t// Not a numeric port label, add it to list to check\n\t\t\t\t\taddServicePort(service.PortLabel, service.Name)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\taddServicePort(service.PortLabel, service.Name)\n\t\t\t}\n\t\t}\n\n\t\t// connect block is only allowed on group level\n\t\tif service.Connect != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"service %q cannot have \\\"connect\\\" block, only services defined in a \\\"group\\\" block can\", service.Name))\n\t\t}\n\n\t\t// Ensure that check names are unique and have valid ports\n\t\tknownChecks := make(map[string]struct{})\n\t\tfor _, check := range service.Checks {\n\t\t\tif _, ok := knownChecks[check.Name]; ok {\n\t\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"check %q is duplicate\", check.Name))\n\t\t\t}\n\t\t\tknownChecks[check.Name] = struct{}{}\n\n\t\t\tif check.AddressMode == AddressModeAlloc {\n\t\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"check %q cannot use address_mode=\\\"alloc\\\", only checks defined in a \\\"group\\\" service block can use this mode\", service.Name))\n\t\t\t}\n\n\t\t\tif check.AddressMode == AddressModeAllocIPv6 {\n\t\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"check %q cannot use address_mode=\\\"alloc_ipv6\\\", only checks defined in a \\\"group\\\" service block can use this mode\", service.Name))\n\t\t\t}\n\n\t\t\tif !check.RequiresPort() {\n\t\t\t\t// No need to continue validating check if it doesn't need a port\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\teffectivePort := check.PortLabel\n\t\t\tif effectivePort == \"\" {","sourceCodeStart":8504,"sourceCodeEnd":8540,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L8504-L8540","documentation":"Within a single service, checks must have unique names. Nomad iterates service.Checks with a knownChecks set keyed by check.Name and rejects a second check with the same name, since duplicate names make Consul health checks ambiguous and unreferenceable.","triggerScenarios":"Submitting a job where one service block declares two `check` stanzas with the same `name` (including checks relying on the default name derivation).","commonSituations":"Copy-pasting a check stanza to add a second port/endpoint and forgetting to rename it; templated job generation emitting identical check names per protocol (http vs tcp) without renaming.","solutions":["Give one of the duplicate checks a distinct name, e.g. name = \"http-alive\" vs \"tcp-alive\".","Remove the redundant check if it duplicates an existing one.","If different check types are intended, verify each check has a unique, descriptive name."],"exampleFix":"// before\nservice {\n  name = \"web\"\n  check { name = \"alive\"; type = \"http\" }\n  check { name = \"alive\"; type = \"tcp\" }\n}\n\n// after\nservice {\n  name = \"web\"\n  check { name = \"http-alive\"; type = \"http\" }\n  check { name = \"tcp-alive\"; type = \"tcp\" }\n}","handlingStrategy":"validation","validationCode":"for _, svc := range allServices {\n  names := map[string]bool{}\n  for _, c := range svc.Checks {\n    if names[c.Name] {\n      return fmt.Errorf(\"service %q: duplicate check %q\", svc.Name, c.Name)\n    }\n    names[c.Name] = true\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Name every check explicitly and descriptively (e.g. http-probe, tcp-probe)","When copy-pasting checks, rename immediately","Enforce check-name uniqueness in job templating code"],"tags":["nomad","health-check","duplicate","service-validation"],"backgroundTag":"duplicate-health-check","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}