hashicorp/nomad · error

artifact must not be nil

Error message

artifact must not be nil

What it means

ArtifactConfig.Validate on Nomad's client artifact configuration struct first guards against being invoked on a nil pointer. Because the method is called on *ArtifactConfig, a nil receiver means the artifact config section was absent or misassembled before validation; rather than panicking on field access it returns this explicit error. It indicates a wiring/assembly problem in the config loading code rather than a bad user value.

Source

Thrown at nomad/structs/config/artifact.go:163

	case !pointer.Eq(a.DecompressionFileCountLimit, o.DecompressionFileCountLimit):
		return false
	case !pointer.Eq(a.DecompressionSizeLimit, o.DecompressionSizeLimit):
		return false
	case !pointer.Eq(a.DisableArtifactInspection, o.DisableArtifactInspection):
		return false
	case !pointer.Eq(a.DisableFilesystemIsolation, o.DisableFilesystemIsolation):
		return false
	case !helper.SliceSetEq(a.FilesystemIsolationExtraPaths, o.FilesystemIsolationExtraPaths):
		return false
	case !pointer.Eq(a.SetEnvironmentVariables, o.SetEnvironmentVariables):
		return false
	}
	return true
}

func (a *ArtifactConfig) Validate() error {
	if a == nil {
		return fmt.Errorf("artifact must not be nil")
	}

	if a.HTTPReadTimeout == nil {
		return fmt.Errorf("http_read_timeout must be set")
	}
	if v, err := time.ParseDuration(*a.HTTPReadTimeout); err != nil {
		return fmt.Errorf("http_read_timeout not a valid duration: %w", err)
	} else if v < 0 {
		return fmt.Errorf("http_read_timeout must be > 0")
	}

	if a.HTTPMaxSize == nil {
		return fmt.Errorf("http_max_size must be set")
	}
	if v, err := humanize.ParseBytes(*a.HTTPMaxSize); err != nil {
		return fmt.Errorf("http_max_size not a valid size: %w", err)
	} else if v > math.MaxInt64 {
		return fmt.Errorf("http_max_size must be < %d but found %d", int64(math.MaxInt64), v)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Initialize the ArtifactConfig (Use Nomad's DefaultArtifactConfig()) before calling Validate.
  2. Fix the config loader so the artifact section is always populated with defaults when absent.
  3. Guard at the call site: if cfg.Artifact == nil { cfg.Artifact = DefaultArtifactConfig() }.
  4. Update to a Nomad version where config assembly fills in defaults automatically.

Example fix

// before
err := cfg.Artifact.Validate()
// after
if cfg.Artifact == nil {
    cfg.Artifact = config.DefaultArtifactConfig()
}
err := cfg.Artifact.Validate()
Defensive patterns

Strategy: type-guard

Validate before calling

if cfg.Artifact == nil {
    cfg.Artifact = config.DefaultArtifactConfig()
}

Type guard

func ensureArtifactConfig(a *config.ArtifactConfig) *config.ArtifactConfig {
    if a == nil {
        return config.DefaultArtifactConfig()
    }
    return a
}

Try / catch

if err := cfg.Artifact.Validate(); err != nil {
    if strings.Contains(err.Error(), "must not be nil") {
        // config assembly bug: wire defaults and retry
    }
    return err
}

Prevention

When it happens

Trigger: Calling clientConfig.Artifact.Validate() (directly or via config validation in nomad agent startup) when the Artifact *ArtifactConfig pointer is nil - e.g. a nil entry in a config map or a loader that skipped populating the defaults.

Common situations: Custom config-loading code that builds Nomad agent config maps with a nil artifact key; tests calling Validate on a zero-value wrapper; version upgrades where a previously optional section is now expected to exist.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/1f1b5a210d58a545. Report an issue: GitHub.