{"record":{"id":"4a89dbb3b15e7400","repo":"hashicorp/nomad","slug":"max-identity-ttl-must-be-greater-than-0","errorCode":null,"errorMessage":"max_identity_ttl must be greater than 0","messagePattern":"max_identity_ttl must be greater than 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/node.go","lineNumber":939,"sourceCode":"\t\treturn fmt.Errorf(\"cannot be empty\")\n\t}\n\n\tvar mErr *multierror.Error\n\n\tswitch n.Enforcement {\n\tcase NodeIntroductionEnforcementNone,\n\t\tNodeIntroductionEnforcementWarn,\n\t\tNodeIntroductionEnforcementStrict:\n\tdefault:\n\t\tmErr = multierror.Append(mErr, fmt.Errorf(\"invalid enforcement %q\", n.Enforcement))\n\t}\n\n\tif n.DefaultIdentityTTL < 1 {\n\t\tmErr = multierror.Append(mErr, errors.New(\"default_identity_ttl must be greater than 0\"))\n\t}\n\n\tif n.MaxIdentityTTL < 1 {\n\t\tmErr = multierror.Append(mErr, errors.New(\"max_identity_ttl must be greater than 0\"))\n\t}\n\n\tif n.MaxIdentityTTL < n.DefaultIdentityTTL {\n\t\tmErr = multierror.Append(mErr, errors.New(\n\t\t\t\"max_identity_ttl must be greater than or equal to default_identity_ttl\",\n\t\t))\n\t}\n\n\treturn mErr.ErrorOrNil()\n}\n\n// NodeIntroductionIdentityClaims contains the claims for node introduction.\ntype NodeIntroductionIdentityClaims struct {\n\tNodePool string `json:\"nomad_node_pool\"`\n\tNodeName string `json:\"nomad_node_name\"`\n}\n\n// GenerateNodeIntroductionIdentityClaims generates a new identity JWT for node","sourceCodeStart":921,"sourceCodeEnd":957,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/node.go#L921-L957","documentation":"Config validation appends this error to a multierror when MaxIdentityTTL is less than 1 (zero or negative). The maximum workload identity token TTL must be a positive duration for the server to issue or bound identity tokens. It is returned as part of the aggregate error from Start/monitor paths.","triggerScenarios":"Setting `max_identity_ttl` to 0 or negative in agent/node configuration and then starting the agent or invoking code that validates the config, producing the aggregated multierror containing this message.","commonSituations":"Omitted max_identity_ttl option defaulting to the zero value; duration parsing errors (empty or malformed string becoming 0); copied config snippets where the max line was commented out while default_identity_ttl remained.","solutions":["Set max_identity_ttl to a positive duration in the config (e.g. max_identity_ttl = \"12h\").","Also verify default_identity_ttl is set — both are required and validated together.","Fix any duration parsing/template rendering that silently produces 0, then restart the agent."],"exampleFix":"# before\nnode {\n  default_identity_ttl = \"1h\"\n}\n# after\nnode {\n  default_identity_ttl = \"1h\"\n  max_identity_ttl = \"12h\"\n}","handlingStrategy":"validation","validationCode":"if cfg.MaxIdentityTTL < 1 {\n\treturn fmt.Errorf(\"max_identity_ttl must be set to a positive duration, got %d\", cfg.MaxIdentityTTL)\n}","typeGuard":null,"tryCatchPattern":"if err := ll.Start(ctx, fns...); err != nil {\n\tif strings.Contains(err.Error(), \"max_identity_ttl must be greater than 0\") {\n\t\treturn fmt.Errorf(\"fix max identity TTL config: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Set max_identity_ttl explicitly; never rely on zero values.","Validate all TTL fields together in one pre-flight check.","Guard duration parsing against empty/malformed inputs that coerce to 0."],"tags":["nomad","config","validation","ttl"],"backgroundTag":"invalid-config-value","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}