hashicorp/nomad · error
Malformed constraint: %s
Error message
Malformed constraint: %s
What it means
parseSingle in the semver constraints package fails when a single constraint string does not match constraintRegexp, i.e. it is not of the form <operator><whitespace?><version>. The whole NewConstraint call returns this error without parsing anything. It is a pure input-syntax error on the caller-supplied constraint string.
Source
Thrown at helper/constraints/semver/constraints.go:109
csStr[i] = c.String()
}
return strings.Join(csStr, ",")
}
// Check tests if a constraint is validated by the given version.
func (c *Constraint) Check(v *version.Version) bool {
return c.f(v, c.check)
}
func (c *Constraint) String() string {
return c.original
}
func parseSingle(v string) (*Constraint, error) {
matches := constraintRegexp.FindStringSubmatch(v)
if matches == nil {
return nil, fmt.Errorf("Malformed constraint: %s", v)
}
check, err := version.NewSemver(matches[2])
if err != nil {
return nil, err
}
return &Constraint{
f: constraintOperators[matches[1]],
check: check,
original: v,
}, nil
}
//-------------------------------------------------------------------
// Constraint functions
//-------------------------------------------------------------------
View on GitHub (pinned to 482b49bf1a)
Solutions
- Inspect the %s in the message to find the offending token and correct its syntax: operator (>=, >, <, <=, =, ~>) immediately followed by a valid semver.
- Validate the constraint string with a regex or NewConstraint in a dry-run before persisting or using it in config.
- Check that version components are numeric and the version parses (cross-check with version.NewSemver).
- Sanitize user-supplied constraint input and reject empty tokens before calling NewConstraint.
Example fix
// before
c, err := constraints.NewConstraint("~> 1.2") // unsupported operator/version
// after
c, err := constraints.NewConstraint(">= 1.2.0, < 2.0.0")
if err != nil {
return fmt.Errorf("invalid constraint %q: %w", raw, err)
} Defensive patterns
Strategy: validation
Validate before calling
var constraintRe = regexp.MustCompile(`^(>=|<=|>|<|=|~>)?\s*v?\d+(\.\d+){0,2}([-+].*)?$`)
func validConstraint(s string) bool {
s = strings.TrimSpace(s)
if s == "" { return false }
return constraintRe.MatchString(s)
}
// usage:
if !validConstraint(userInput) {
return fmt.Errorf("invalid constraint %q", userInput)
} Try / catch
c, err := constraints.NewConstraint(raw)
if err != nil {
if strings.HasPrefix(err.Error(), "Malformed constraint") {
return fmt.Errorf("constraint %q is not valid syntax: %w", raw, err)
}
return err
} Prevention
- Only use operators supported by hashicorp/go-version: =, !=, >, <, >=, <=, ~> — not ecosystem-specific ones like Ruby's pessimistic pin without a valid version.
- Always pair an operator with a valid numeric semver (no wildcards like 1.x).
- Trim and validate user/config-supplied constraint strings before calling NewConstraint; reject empty tokens from comma-splitting.
- Unit-test all constraint strings shipped in your config with NewConstraint at startup and fail fast.
When it happens
Trigger: NewConstraint("~> 1.2") or other operators unsupported by this regex; missing version (">= "); non-numeric versions (">= v1.x"); stray characters (">=1.0.0!"); splitting a compound constraint incorrectly so an empty or malformed token is parsed.
Common situations: Hand-written version pins in config files with typos; constraints copied from other ecosystems (e.g. Ruby's "~>" pessimistic operator) that hashicorp/go-version doesn't support; empty strings produced by splitting on ","; user-supplied constraint input not validated upstream.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- <combined HCL diagnostics from str.String()>
- error parsing address %q: not an IP address
- error parsing port %q: %v
- Invalid key value pair for topic, topic: %s
- could not parse value as bytes: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/a867bdc5264848b1.
Report an issue: GitHub.