{"record":{"id":"5395aae7694ad608","repo":"hashicorp/nomad","slug":"client-introduction-enforcement-must-be-set","errorCode":null,"errorMessage":"client_introduction.enforcement must be set","messagePattern":"client_introduction\\.enforcement must be set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/config.go","lineNumber":1261,"sourceCode":"\t\tresult.MaxIdentityTTL = z.MaxIdentityTTL\n\t}\n\tif len(z.ExtraKeysHCL) > 0 {\n\t\tresult.ExtraKeysHCL = append(result.ExtraKeysHCL, z.ExtraKeysHCL...)\n\t}\n\n\treturn &result\n}\n\n// Validate performs validation on the ClientIntroduction configuration block to\n// ensure the values are set correctly for use by the server.\nfunc (c *ClientIntroduction) Validate() error {\n\n\tif c == nil {\n\t\treturn nil\n\t}\n\n\tif c.Enforcement == \"\" {\n\t\treturn errors.New(\"client_introduction.enforcement must be set\")\n\t}\n\tif !slices.Contains(ClientIntroductionEnforcementValues, c.Enforcement) {\n\t\treturn fmt.Errorf(\"client_introduction.enforcement must be one of %v\",\n\t\t\tClientIntroductionEnforcementValues)\n\t}\n\n\tif c.DefaultIdentityTTL < 1 {\n\t\treturn errors.New(\"client_introduction.default_identity_ttl must be greater one\")\n\t}\n\tif c.MaxIdentityTTL < 1 {\n\t\treturn errors.New(\"client_introduction.max_identity_ttl must be greater one\")\n\t}\n\tif c.MaxIdentityTTL < c.DefaultIdentityTTL {\n\t\treturn errors.New(\"client_introduction.max_identity_ttl must be greater than default_identity_ttl\")\n\t}\n\n\treturn nil\n}","sourceCodeStart":1243,"sourceCodeEnd":1279,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/config.go#L1243-L1279","documentation":"The `client_introduction` block requires an `enforcement` setting that selects how the agent handles client auto-introduction. Validate() refuses to continue when `Enforcement` is the empty string because the behavior would otherwise be undefined. A second check (next error) verifies the value is one of the known ClientIntroductionEnforcementValues.","triggerScenarios":"Agent config defines a `client_introduction { ... }` block but omits the `enforcement` key, so the parsed struct's Enforcement field is \"\" when its Validate() runs during agent startup/config parse.","commonSituations":"Adding a client_introduction stanza after reading docs for an older version that defaulted enforcement; renaming the key (e.g. `mode` instead of `enforcement`); YAML/HCL indentation mistakes leaving enforcement outside the block.","solutions":["Add `enforcement = \"<one of the supported values>\"` inside the client_introduction block (see ClientIntroductionEnforcementValues for valid options).","If you don't need client introduction at all, remove the entire client_introduction block.","Check the key spelling and that it is nested inside client_introduction, not a sibling block."],"exampleFix":"// before\nclient_introduction {\n  default_identity_ttl = \"1h\"\n}\n\n// after\nclient_introduction {\n  enforcement           = \"serve-and-mark\"\n  default_identity_ttl  = \"1h\"\n}","handlingStrategy":"validation","validationCode":"if cfg.ClientIntroduction != nil && cfg.ClientIntroduction.Enforcement == \"\" {\n    return errors.New(\"client_introduction.enforcement must be set before starting the agent\")\n}\nif cfg.ClientIntroduction != nil && !slices.Contains(ClientIntroductionEnforcementValues, cfg.ClientIntroduction.Enforcement) {\n    return fmt.Errorf(\"enforcement must be one of %v\", ClientIntroductionEnforcementValues)\n}","typeGuard":"func enforcementSet(c *ClientIntroduction) bool {\n    return c != nil && slices.Contains(ClientIntroductionEnforcementValues, c.Enforcement)\n}","tryCatchPattern":null,"preventionTips":["Always specify enforcement explicitly when using the client_introduction block.","Keep a canonical example config snippet in your repo and copy from it.","Run `agent config validate` (or equivalent) in CI before deploys."],"tags":["config-validation","client-introduction","missing-field","startup"],"backgroundTag":"missing-required-argument","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"}