hashicorp/nomad · error

Failed to parse value of %qq (%v) as a bool: %v

Error message

Failed to parse value of %qq (%v) as a bool: %v

What it means

jobDelete (command/agent/job_endpoint.go:659) parses the ?no_shutdown_delay= query parameter with strconv.ParseBool and wraps failures in this error. Note the format string contains a typo (%qq instead of %q), so the field name is rendered with a stray 'q' in the message. The delete request is rejected; the job keeps its existing shutdown-delay behavior.

Source

Thrown at command/agent/job_endpoint.go:659

			return nil, fmt.Errorf("Failed to parse value of %q (%v) as a bool: %v", "global", globalStr, err)
		}
	}
	args.Global = globalBool

	// Parse the eval priority from the request URL query if present.
	evalPriority, err := parseInt(req, "eval_priority")
	if err != nil {
		return nil, err
	}

	// Identify the no_shutdown_delay query param and parse.
	noShutdownDelayStr := req.URL.Query().Get("no_shutdown_delay")
	var noShutdownDelay bool
	if noShutdownDelayStr != "" {
		var err error
		noShutdownDelay, err = strconv.ParseBool(noShutdownDelayStr)
		if err != nil {
			return nil, fmt.Errorf("Failed to parse value of %qq (%v) as a bool: %v", "no_shutdown_delay", noShutdownDelayStr, err)
		}
	}
	args.NoShutdownDelay = noShutdownDelay

	// Validate the evaluation priority if the user supplied a non-default
	// value. It's more efficient to do it here, within the agent rather than
	// sending a bad request for the server to reject.
	if evalPriority != nil && *evalPriority > 0 {
		if err := validateEvalPriorityOpt(*evalPriority); err != nil {
			return nil, err
		}
		args.EvalPriority = *evalPriority
	}

	s.parseWriteRequest(req, &args.WriteRequest)

	var out structs.JobDeregisterResponse
	if err := s.agent.RPC("Job.Deregister", &args, &out); err != nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Send no_shutdown_delay=true or no_shutdown_delay=false (1/0/t/f variants also accepted).
  2. Omit the parameter to leave the job's shutdown delay unchanged.
  3. Ignore the stray 'q' in the message; it is a formatting typo — the quoted field is still no_shutdown_delay and %v shows the bad value.
  4. Fix the serializing client to emit Go-acceptable boolean strings.

Example fix

// before
curl -X DELETE 'http://127.0.0.1:4646/v1/job/web?no_shutdown_delay=yes'
// after
curl -X DELETE 'http://127.0.0.1:4646/v1/job/web?no_shutdown_delay=true'
Defensive patterns

Strategy: validation

Validate before calling

// Before DELETE with no_shutdown_delay
if nsd != "" {
    if _, err := strconv.ParseBool(nsd); err != nil {
        return fmt.Errorf("no_shutdown_delay must be a bool, got %q", nsd)
    }
}

Type guard

func isNoShutdownDelayParam(s string) bool {
    _, err := strconv.ParseBool(s)
    return s == "" || err == nil
}

Try / catch

resp, err := httpDo(http.MethodDelete, jobURL+"?no_shutdown_delay="+nsd, nil)
if err != nil { return err }
if resp.StatusCode == 400 {
    // message contains a formatting typo (%qq) but cause is the same: bad bool
    return deleteJob(jobID, "no_shutdown_delay=false")
}

Prevention

When it happens

Trigger: DELETE /v1/job/<job-id>?no_shutdown_delay=<bad value> — e.g. no_shutdown_delay=yes, no_shutdown_delay=skip, no_shutdown_delay=0.0. Any non-empty string outside strconv.ParseBool's accepted literal set triggers it.

Common situations: Scripts passing human words ('skip', 'yes') for shutdown-delay override; clients passing a numeric 0/1.0 pair where '1.0' fails; query strings built from YAML/JSON config where the value was typed as a string instead of bool.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


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