{"record":{"id":"5e814363b721ff46","repo":"hashicorp/nomad","slug":"filter-rule-must-begin-with-either-or-q","errorCode":null,"errorMessage":"Filter rule must begin with either '+' or '-': %q","messagePattern":"Filter rule must begin with either '\\+' or '-': %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/config.go","lineNumber":1509,"sourceCode":"\tnt.PrefixFilter = slices.Clone(t.PrefixFilter)\n\tnt.FilterDefault = pointer.Copy(t.FilterDefault)\n\tnt.ExtraKeysHCL = slices.Clone(t.ExtraKeysHCL)\n\treturn &nt\n}\n\n// PrefixFilters parses the PrefixFilter field and returns a list of allowed and blocked filters\nfunc (t *Telemetry) PrefixFilters() (allowed, blocked []string, err error) {\n\tfor _, rule := range t.PrefixFilter {\n\t\tif rule == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tswitch rule[0] {\n\t\tcase '+':\n\t\t\tallowed = append(allowed, rule[1:])\n\t\tcase '-':\n\t\t\tblocked = append(blocked, rule[1:])\n\t\tdefault:\n\t\t\treturn nil, nil, fmt.Errorf(\"Filter rule must begin with either '+' or '-': %q\", rule)\n\t\t}\n\t}\n\treturn allowed, blocked, nil\n}\n\n// Validate the telemetry configuration options. These are used by the agent,\n// regardless of mode, so can live here rather than a structs package. It is\n// safe to call, without checking whether the config object is nil first.\nfunc (t *Telemetry) Validate() error {\n\tif t == nil {\n\t\treturn nil\n\t}\n\n\t// Ensure we have durations that are greater than zero.\n\tif t.inMemoryCollectionInterval <= 0 {\n\t\treturn errors.New(\"telemetry in-memory collection interval must be greater than zero\")\n\t}\n\tif t.inMemoryRetentionPeriod <= 0 {","sourceCodeStart":1491,"sourceCodeEnd":1527,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/config.go#L1491-L1527","documentation":"Telemetry.PrefixFilters parses prefix_filter rules; a rule whose first character is neither '+' (allow) nor '-' (block) is invalid, so the telemetry metric filter cannot be built and agent startup/configuration fails.","triggerScenarios":"Passing a filter rule string like \"consul-service\" (no + or - prefix) to the filter parsing in agent config.","commonSituations":"Copy-pasting filter expressions from docs without the prefix; splitting a comma-separated list that strips the leading + or -; users assuming bare names mean 'allow'.","solutions":["Prefix each rule with '+' to allow or '-' to block, e.g. \"+web\", \"-db\".","Check for config parsing that strips the leading character (quoting/escaping issues in HCL).","Trim whitespace only, never the sign, when building rule lists programmatically."],"exampleFix":"// before\nfilters = [\"web\", \"-db\"]\n// after\nfilters = [\"+web\", \"-db\"]","handlingStrategy":"validation","validationCode":"for _, r := range rules {\n  if len(r) == 0 || (r[0] != '+' && r[0] != '-') {\n    return fmt.Errorf(\"rule %q must start with + or -\", r)\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include an explicit +/- prefix on every rule","Add a config linter check for filter rules","Document the prefix convention in config templates"],"tags":["config","validation","filter"],"backgroundTag":"invalid-format-string","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"}