{"record":{"id":"d2bccd0325bed912","repo":"hashicorp/nomad","slug":"decompression-file-count-limit-must-not-be-nil","errorCode":null,"errorMessage":"decompression_file_count_limit must not be nil","messagePattern":"decompression_file_count_limit must not be nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/config/artifact.go","lineNumber":221,"sourceCode":"\t\treturn fmt.Errorf(\"hg_timeout must be set\")\n\t}\n\tif v, err := time.ParseDuration(*a.HgTimeout); err != nil {\n\t\treturn fmt.Errorf(\"hg_timeout not a valid duration: %w\", err)\n\t} else if v < 0 {\n\t\treturn fmt.Errorf(\"hg_timeout must be > 0\")\n\t}\n\n\tif a.S3Timeout == nil {\n\t\treturn fmt.Errorf(\"s3_timeout must be set\")\n\t}\n\tif v, err := time.ParseDuration(*a.S3Timeout); err != nil {\n\t\treturn fmt.Errorf(\"s3_timeout not a valid duration: %w\", err)\n\t} else if v < 0 {\n\t\treturn fmt.Errorf(\"s3_timeout must be > 0\")\n\t}\n\n\tif a.DecompressionFileCountLimit == nil {\n\t\treturn fmt.Errorf(\"decompression_file_count_limit must not be nil\")\n\t}\n\tif v := *a.DecompressionFileCountLimit; v < 0 {\n\t\treturn fmt.Errorf(\"decompression_file_count_limit must be >= 0 but found %d\", v)\n\t}\n\n\tif a.DecompressionSizeLimit == nil {\n\t\treturn fmt.Errorf(\"decompression_size_limit must not be nil\")\n\t}\n\tif v, err := humanize.ParseBytes(*a.DecompressionSizeLimit); err != nil {\n\t\treturn fmt.Errorf(\"decompression_size_limit is not a valid size: %w\", err)\n\t} else if v > math.MaxInt64 {\n\t\treturn fmt.Errorf(\"decompression_size_limit must be < %d but found %d\", int64(math.MaxInt64), v)\n\t}\n\n\tif a.DisableArtifactInspection == nil {\n\t\treturn fmt.Errorf(\"disable_artifact_inspection must be set\")\n\t}\n","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/config/artifact.go#L203-L239","documentation":"Validate() requires decompression_file_count_limit to be explicitly present; a nil pointer fails with 'decompression_file_count_limit must not be nil'. Nomad uses this limit to cap how many files an artifact archive may contain during decompression (zip-slip / bomb protection).","triggerScenarios":"Calling ArtifactConfig.Validate() on a struct where the decompression_file_count_limit key is missing, leaving a.DecompressionFileCountLimit as nil *int.","commonSituations":"Manually built ArtifactConfig structs in tests/plugins; pre-existing config files from Nomad versions before this limit existed; template engines that omit keys with unset variables; partial merges dropping the field.","solutions":["Add decompression_file_count_limit = 10000 (or another suitable non-negative int) to the artifact block.","Build the config from DefaultArtifactConfig() and override only what you need.","Fix config merge logic so defaults fill absent keys instead of leaving nil pointers."],"exampleFix":"// before\nartifact {\n  # decompression_file_count_limit missing\n}\n// after\nartifact {\n  decompression_file_count_limit = 10000\n}","handlingStrategy":"validation","validationCode":"if cfg.DecompressionFileCountLimit == nil {\n    return errors.New(\"artifact config must set decompression_file_count_limit\")\n}","typeGuard":"func hasFileCountLimit(a *ArtifactConfig) bool { return a.DecompressionFileCountLimit != nil && *a.DecompressionFileCountLimit >= 0 }","tryCatchPattern":null,"preventionTips":["Use DefaultArtifactConfig() as the base for all config construction.","After Nomad upgrades, diff your artifact block against the new defaults.","Fail fast in tests by calling Validate() on fixture configs."],"tags":["nomad","config-validation","missing-field","decompression"],"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"}