{"record":{"id":"9baf134e4e435f03","repo":"hashicorp/nomad","slug":"error-marshaling-volume-pramaters-w","errorCode":null,"errorMessage":"error marshaling volume pramaters: %w","messagePattern":"error marshaling volume pramaters: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/hostvolumemanager/host_volume_plugin.go","lineNumber":334,"sourceCode":"// - DHV_NODE_POOL={Nomad node pool}\n// - DHV_CAPACITY_MIN_BYTES={capacity_min from the volume spec, expressed in bytes}\n// - DHV_CAPACITY_MAX_BYTES={capacity_max from the volume spec, expressed in bytes}\n// - DHV_PARAMETERS={stringified json of parameters from the volume spec}\n//\n// Response should be valid JSON on stdout with \"path\" and \"bytes\", e.g.:\n// {\"path\": \"/path/that/was/created\", \"bytes\": 50000000}\n// \"path\" must be provided to confirm the requested path is what was\n// created by the plugin. \"bytes\" is the actual size of the volume created\n// by the plugin; if excluded, it will default to 0.\n//\n// Must complete within 60 seconds (timeout on RPC)\nfunc (p *HostVolumePluginExternal) Create(ctx context.Context,\n\treq *cstructs.ClientHostVolumeCreateRequest) (*HostVolumePluginCreateResponse, error) {\n\n\tparams, err := json.Marshal(req.Parameters)\n\tif err != nil {\n\t\t// should never happen; req.Parameters is a simple map[string]string\n\t\treturn nil, fmt.Errorf(\"error marshaling volume pramaters: %w\", err)\n\t}\n\tenvVars := []string{\n\t\tfmt.Sprintf(\"%s=%s\", EnvOperation, \"create\"),\n\t\tfmt.Sprintf(\"%s=%s\", EnvVolumesDir, p.VolumesDir),\n\t\tfmt.Sprintf(\"%s=%s\", EnvPluginDir, p.PluginDir),\n\t\tfmt.Sprintf(\"%s=%s\", EnvNodePool, p.NodePool),\n\t\t// values from volume spec\n\t\tfmt.Sprintf(\"%s=%s\", EnvNamespace, req.Namespace),\n\t\tfmt.Sprintf(\"%s=%s\", EnvVolumeName, req.Name),\n\t\tfmt.Sprintf(\"%s=%s\", EnvVolumeID, req.ID),\n\t\tfmt.Sprintf(\"%s=%d\", EnvCapacityMin, req.RequestedCapacityMinBytes),\n\t\tfmt.Sprintf(\"%s=%d\", EnvCapacityMax, req.RequestedCapacityMaxBytes),\n\t\tfmt.Sprintf(\"%s=%s\", EnvNodeID, req.NodeID),\n\t\tfmt.Sprintf(\"%s=%s\", EnvParameters, params),\n\t}\n\n\tvar pluginResp HostVolumePluginCreateResponse\n\tlog := p.log.With(\"volume_name\", req.Name, \"volume_id\", req.ID)","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/hostvolumemanager/host_volume_plugin.go#L316-L352","documentation":"This error is returned by HostVolumePluginExternal.Create when the host volume plugin fails to JSON-marshal the request's Parameters map before invoking the external plugin executable. The comment notes it 'should never happen' since Parameters is a simple map[string]string, so it indicates the map contains a value that the encoding/json package cannot serialize (or a corrupted request). It wraps the underlying json.Marshal error via %w.","triggerScenarios":"Calling HostVolumePluginExternal.Create with a ClientHostVolumeCreateRequest whose Parameters map contains a value that fails json.Marshal — practically only possible if the map is not really map[string]string (e.g. custom JSON marshaler panics/returns error, or unsupported type injected elsewhere).","commonSituations":"A client or API layer constructing volume parameters with unexpected types; a custom type implementing MarshalJSON that returns an error; upgraded Nomad code where Parameters typing changed; memory corruption or concurrent map mutation during marshal.","solutions":["Inspect req.Parameters and ensure it is a plain map[string]string with JSON-safe values","Log the wrapped error (%w) to identify which key/value failed to marshal","Rebuild the create request with simple string parameters","If using a custom map type, fix or remove its MarshalJSON implementation","Upgrade/verify Nomad version — this is normally an unreachable defensive branch"],"exampleFix":"// before\nreq := &cstructs.ClientHostVolumeCreateRequest{Parameters: badParams}\nresp, err := plugin.Create(ctx, req)\n// after\nparams := make(map[string]string, len(raw))\nfor k, v := range raw { params[k] = fmt.Sprintf(\"%v\", v) }\nreq := &cstructs.ClientHostVolumeCreateRequest{Parameters: params}\nresp, err := plugin.Create(ctx, req)","handlingStrategy":"validation","validationCode":"params := req.Parameters\nfor k, v := range params {\n    if k == \"\" { return fmt.Errorf(\"empty parameter key\") }\n    _ = v // map[string]string always marshals; otherwise inspect custom types\n}\nif b, err := json.Marshal(params); err != nil {\n    return fmt.Errorf(\"parameters not serializable: %w\", err)\n}","typeGuard":"func okParams(m map[string]string) bool { return m != nil }","tryCatchPattern":"resp, err := plugin.Create(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"error marshaling volume pramaters\") {\n        // fix Parameters map client-side and retry once\n        return fmt.Errorf(\"bad volume parameters: %w\", err)\n    }\n    return err\n}","preventionTips":["Always pass a plain map[string]string for volume parameters","Never attach custom types with fallible MarshalJSON to request fields","Pre-sanitize parameters before building the request","Treat this error as an upstream bug report trigger"],"tags":["json","host-volumes","serialization"],"backgroundTag":"json-marshal-failed","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"}