hashicorp/nomad · error

unknown mkdir parameter: %q

Error message

unknown mkdir parameter: %q

What it means

decodeMkdirParams parses the key/value parameter map passed to the plugin's Create operation into a MkdirParams struct (path, mode, uid, gid). This error is raised when a parameter key outside the recognized set ("path", "mode", "uid", "gid") is supplied. It indicates a contract mismatch between the caller building the parameters and the plugin's decoder — usually a typo or a plugin/version where new parameters were added.

Source

Thrown at client/hostvolumemanager/host_volume_plugin.go:192

	}
	var err error

	for param, val := range in {
		switch param {
		case "mode":
			// mode needs special treatment - it's octal. note that this does
			// not check whether it's a *reasonable* mode for a directory.
			// that will be discovered during MkdirAll and subsequent usage
			// by workloads (which we cannot predict).
			var number uint64
			number, err = strconv.ParseUint(val, 8, 32)
			out.Mode = os.FileMode(number)
		case "uid":
			out.Uid, err = strconv.Atoi(val)
		case "gid":
			out.Gid, err = strconv.Atoi(val)
		default:
			err = fmt.Errorf("unknown mkdir parameter: %q", param)
		}
		if err != nil {
			return out, fmt.Errorf("invalid value for %q: %w", param, err)
		}
	}

	return out, nil
}

func (p *HostVolumePluginMkdir) Delete(_ context.Context, req *cstructs.ClientHostVolumeDeleteRequest) error {
	path := filepath.Join(p.VolumesDir, req.ID)
	log := p.log.With(
		"operation", "delete",
		"volume_id", req.ID,
		"path", path)
	log.Debug("running plugin")

	err := os.RemoveAll(path)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Correct the parameter key to one of the supported names: "path", "mode", "uid", "gid".
  2. Check for typos by comparing the keys in your request against the decodeMkdirParams switch cases.
  3. Upgrade the external host volume plugin binary to match the Nomad client version if a newly introduced parameter is being sent.
  4. Log the full parameter map before calling Create to confirm exactly what is passed.

Example fix

// before
params := map[string]string{"path": "/vols/data", "permissions": "0755"}

// after
params := map[string]string{"path": "/vols/data", "mode": "0755"}
Defensive patterns

Strategy: validation

Validate before calling

var allowedMkdirParams = map[string]bool{"path": true, "mode": true, "uid": true, "gid": true}

func validateMkdirParams(params map[string]string) error {
    for k := range params {
        if !allowedMkdirParams[k] {
            return fmt.Errorf("unsupported mkdir parameter %q; allowed: path, mode, uid, gid", k)
        }
    }
    return nil
}

Try / catch

if err != nil && strings.Contains(err.Error(), "unknown mkdir parameter") {
    re := regexp.MustCompile(`unknown mkdir parameter: "([^"]+)"`)
    if m := re.FindStringSubmatch(err.Error()); m != nil {
        log.Error("remove or rename parameter", "param", m[1])
    }
}

Prevention

When it happens

Trigger: Calling Create with a params map containing a key not in {path, mode, uid, gid}, e.g. "owner" instead of "uid", "permissions" instead of "mode", or a parameter introduced by a newer Nomad version sent to an older external plugin binary.

Common situations: Typo in job/API host volume parameters; custom tooling generating the parameter map; version skew between the Nomad client and an external host volume plugin binary (new parameter names unknown to old plugin).

Related errors


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