{"record":{"id":"92d031fa3c184ccd","repo":"hashicorp/nomad","slug":"expose-may-only-be-set-for-consul-service-checks","errorCode":null,"errorMessage":"expose may only be set for Consul service checks","messagePattern":"expose may only be set for Consul service checks","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/services.go","lineNumber":359,"sourceCode":"\n\t// validate check_restart\n\tif err := sc.CheckRestart.Validate(); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// validate a Service's ServiceCheck in the context of the Nomad provider.\nfunc (sc *ServiceCheck) validateNomad() error {\n\tallowable := []string{ServiceCheckTCP, ServiceCheckHTTP}\n\tif err := sc.validateCommon(allowable); err != nil {\n\t\treturn err\n\t}\n\n\t// expose is connect (consul) specific\n\tif sc.Expose {\n\t\treturn errors.New(\"expose may only be set for Consul service checks\")\n\t}\n\n\t// nomad checks do not have warnings\n\tif sc.OnUpdate == OnUpdateIgnoreWarn {\n\t\treturn errors.New(\"on_update may only be set to ignore_warnings for Consul service checks\")\n\t}\n\n\t// below are temporary limitations on checks in nomad\n\t// https://github.com/hashicorp/team-nomad/issues/354\n\n\t// check_restart.ignore_warnings is not a thing in Nomad (which has no warnings in checks)\n\tif sc.CheckRestart != nil {\n\t\tif sc.CheckRestart.IgnoreWarnings {\n\t\t\treturn errors.New(\"ignore_warnings on check_restart only supported for Consul service checks\")\n\t\t}\n\t}\n\n\t// address_mode=\"driver\" not yet supported on nomad","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/services.go#L341-L377","documentation":"In Nomad service checks (validateNomad path), the expose field is a Consul Connect-specific feature; setting it on a check of a service that is not backed by Consul is rejected. Nomad-side checks have no envoy expose configuration.","triggerScenarios":"A job defines a service check with expose = true while the service provider is not Consul (e.g. provider = \"nomad\" or no connect block).","commonSituations":"Copying Consul connect service stanzas into nomad-provider services; enabling expose for a plain Nomad check; converting jobs from Consul to Nomad service discovery without removing expose.","solutions":["Remove expose = true from the check","Switch the service to provider = \"consul\" with a connect stanza if expose is genuinely needed","Re-run nomad job validate to confirm"],"exampleFix":"// before\nservice {\n  provider = \"nomad\"\n  check {\n    expose = true\n  }\n}\n// after\nservice {\n  provider = \"nomad\"\n  check {\n    # expose removed\n  }\n}","handlingStrategy":"validation","validationCode":"if check.Expose && service.Provider != \"consul\" {\n    return fmt.Errorf(\"check %q: expose requires provider = \\\"consul\\\"\", check.Name)\n}","typeGuard":null,"tryCatchPattern":"if err := job.Validate(); err != nil {\n    var ve *jobValidationError\n    if errors.As(err, &ve) && strings.Contains(ve.Error(), \"expose may only be set\") {\n        // strip expose or switch provider to consul\n    }\n}","preventionTips":["Only set expose on services inside a connect block with Consul provider","Lint job files for consul-only fields on nomad services","Run nomad job validate in CI"],"tags":["nomad","consul","service-check","validation"],"backgroundTag":"unsupported-check-option","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"}