tsenart/vegeta · error
bad header: %s
Error message
bad header: %s
What it means
Returned when a header line in the targets file has no ':' separator, so it cannot be split into key/value. The parser requires header lines of the form "Key: Value".
Source
Thrown at lib/targets.go:320
tgt.URL = tokens[1]
line = strings.TrimSpace(sc.Peek())
if line == "" || startsWithHTTPMethod(line) {
return nil
}
for sc.Scan() {
if line = strings.TrimSpace(sc.Text()); line == "" {
break
} else if strings.HasPrefix(line, "#") {
continue
} else if strings.HasPrefix(line, "@") {
if tgt.Body, err = os.ReadFile(line[1:]); err != nil {
return fmt.Errorf("bad body: %w", err)
}
break
}
tokens = strings.SplitN(line, ":", 2)
if len(tokens) < 2 {
return fmt.Errorf("bad header: %s", line)
}
for i := range tokens {
if tokens[i] = strings.TrimSpace(tokens[i]); tokens[i] == "" {
return fmt.Errorf("bad header: %s", line)
}
}
// Add key/value directly to the http.Header (map[string][]string).
// http.Header.Add() canonicalizes keys but vegeta is used
// to test systems that require case-sensitive headers.
tgt.Header[tokens[0]] = append(tgt.Header[tokens[0]], tokens[1])
}
if err = sc.Err(); err != nil {
return ErrNoTargets
}
return nil
}
}
View on GitHub (pinned to cf58112690)
Solutions
- Format every header line as "Key: Value" with a colon separating them.
- Remove stray lines (or prefix with '#') that are not method/URL, header, body '@' line, or blank.
- Check the offending line text in the error and add the missing colon.
- Avoid pasting curl command syntax directly into targets files.
Example fix
// before GET http://api/ Authorization Bearer xyz // after GET http://api/ Authorization: Bearer xyz
Defensive patterns
Strategy: validation
Validate before calling
func validHeaderLine(line string) bool {
return strings.Contains(line, ":") &&
strings.TrimSpace(strings.SplitN(line, ":", 2)[0]) != ""
} Try / catch
if _, err := vegeta.NewTargets(r); err != nil {
if strings.Contains(err.Error(), "bad header:") {
return fmt.Errorf("header lines need 'Key: Value' form: %w", err)
}
return err
} Prevention
- Format header lines strictly as 'Key: Value'.
- Strip curl-style '-H' flags before pasting into targets files.
- Lint targets files for lines missing ':' after the first request line.
When it happens
Trigger: A continuation line in a targets block that lacks a colon, e.g. "Authorization" alone, or a value that accidentally wrapped onto its own line without "Key:".
Common situations: Copy-pasted headers losing the colon, curl -H style flags pasted verbatim ("-H 'X: Y'"), or JSON-ish lines mistakenly included in the target block.
Related errors
AI-assisted analysis of tsenart/vegeta@cf58112690 (2026-08-31).
Data as JSON: /api/errors/30c9f97d321c0507.
Report an issue: GitHub.