{"record":{"id":"531ba042f140f163","repo":"hashicorp/nomad","slug":"job-name-contains-a-null-character","errorCode":null,"errorMessage":"Job Name contains a null character","messagePattern":"Job Name contains a null character","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":4753,"sourceCode":"\n// Validate is used to check a job for reasonable configuration\nfunc (j *Job) Validate() error {\n\tvar mErr multierror.Error\n\n\tif j.Region == \"\" && j.Multiregion == nil {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing job region\"))\n\t}\n\tif j.ID == \"\" {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing job ID\"))\n\t} else if strings.Contains(j.ID, \" \") {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Job ID contains a space\"))\n\t} else if strings.Contains(j.ID, \"\\000\") {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Job ID contains a null character\"))\n\t}\n\tif j.Name == \"\" {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing job name\"))\n\t} else if strings.Contains(j.Name, \"\\000\") {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Job Name contains a null character\"))\n\t}\n\n\tif j.Namespace == \"\" {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Job must be in a namespace\"))\n\t}\n\tswitch j.Type {\n\tcase JobTypeCore, JobTypeService, JobTypeBatch, JobTypeSystem, JobTypeSysBatch:\n\tcase \"\":\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing job type\"))\n\tdefault:\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Invalid job type: %q\", j.Type))\n\t}\n\tif len(j.Datacenters) == 0 && !j.IsMultiregion() {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing job datacenters\"))\n\t} else {\n\t\tfor _, v := range j.Datacenters {\n\t\t\tif v == \"\" {\n\t\t\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Job datacenter must be non-empty string\"))","sourceCodeStart":4735,"sourceCodeEnd":4771,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L4735-L4771","documentation":"Job.Validate() rejects Job Names containing a NUL byte (\"\\000\"). Like the ID check, this guards against control characters that break downstream string handling and storage. It applies only when the Name is non-empty.","triggerScenarios":"Registering a job whose `name` field contains an embedded null byte, usually from programmatic construction (j.Name containing \"\\x00\") or corrupted/deserialized input passed to Job.Validate().","commonSituations":"Untrusted or binary-derived input feeding the job name; string truncation bugs introducing NULs; injection attempts through job-submission APIs.","solutions":["Sanitize the name: strings.ReplaceAll(name, \"\\x00\", \"\") before submission","Validate user-supplied names with ^[^\\x00]+$ at your API boundary","Log the name with %q to reveal hidden control characters when debugging"],"exampleFix":"// before\njob.Name = userInput\n// after\njob.Name = strings.ReplaceAll(userInput, \"\\x00\", \"\")","handlingStrategy":"validation","validationCode":"if strings.Contains(j.Name, \"\\x00\") {\n    return fmt.Errorf(\"job name contains a null character\")\n}","typeGuard":"func isSafeJobName(name string) bool { return name != \"\" && !strings.ContainsRune(name, '\\x00') }","tryCatchPattern":"if err := job.Validate(); err != nil {\n    if strings.Contains(err.Error(), \"Job Name contains a null character\") {\n        job.Name = strings.ReplaceAll(job.Name, \"\\x00\", \"\")\n    }\n}","preventionTips":["Sanitize user-supplied job names before submission","Reject control characters at the input boundary","Log names with %q when debugging encoding issues"],"tags":["nomad","go","validation","control-characters"],"backgroundTag":"invalid-identifier-format","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"}