larksuite/cli · error
emlbuilder: header name contains non-printable character: %q
Error message
emlbuilder: header name contains non-printable character: %q
What it means
validateHeaderName also rejects header names containing any character outside printable ASCII (below 0x21 or above 0x7e), since RFC 5322 field names must be printable ASCII. This keeps serialized headers byte-safe and prevents obfuscation or injection via exotic characters. Wrapped into a typed ValidationError by the mail command layer.
Source
Thrown at shortcuts/mail/emlbuilder/builder.go:176
case r >= 0x202A && r <= 0x202E: // Bidi: LRE/RLE/PDF/LRO/RLO
return true
case r >= 0x2028 && r <= 0x2029: // line/paragraph separator
return true
case r >= 0x2066 && r <= 0x2069: // Bidi isolates: LRI/RLI/FSI/PDI
return true
}
return false
}
// validateHeaderName rejects any string that contains ':', CR (\r), LF (\n),
// or non-printable ASCII characters, as required by RFC 5322 field-name syntax.
func validateHeaderName(n string) error {
if strings.ContainsAny(n, ":\r\n") {
return fmt.Errorf("emlbuilder: header name contains ':', CR, or LF: %q", n) //nolint:forbidigo // intermediate EML builder error; mail command layer wraps into typed ValidationError.
}
for _, r := range n {
if r < 0x21 || r > 0x7e {
return fmt.Errorf("emlbuilder: header name contains non-printable character: %q", n) //nolint:forbidigo // intermediate EML builder error; mail command layer wraps into typed ValidationError.
}
}
return nil
}
// validateDisplayName rejects display names containing CR or LF, which could
// escape the quoted-string encoding used by mail.Address.String() and inject headers.
func validateDisplayName(name string) error {
if strings.ContainsAny(name, "\r\n") {
return fmt.Errorf("emlbuilder: display name contains CR or LF: %q", name) //nolint:forbidigo // intermediate EML builder error; mail command layer wraps into typed ValidationError.
}
return nil
}
// validateCID rejects content IDs containing ASCII control characters (0x00–0x1F, 0x7F).
// RFC 2045 Content-ID has the same syntax as Message-ID; control characters are never valid.
func validateCID(cid string) error {
for _, r := range cid {View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Use only printable ASCII characters (0x21-0x7e, no spaces) in the header name.
- Trim whitespace with strings.TrimSpace before passing the name.
- For non-ASCII metadata, move it into the header value (optionally RFC 2047 encoded) rather than the name.
Example fix
// before
b.Header("X-Kunde Name", v)
// after
b.Header("X-Kunde-Name", v) Defensive patterns
Strategy: validation
Validate before calling
func printableASCIIName(n string) bool {
if n == "" { return false }
for _, r := range n {
if r < 0x21 || r > 0x7e { return false }
}
return true
}
// check before b.Header(strings.TrimSpace(name), value) Try / catch
if err := b.Header(name, value); err != nil {
var verr *ValidationError
if errors.As(err, &verr) { log.Printf("invalid header name %q", name) }
return err
} Prevention
- Restrict custom header names to ^[!-~]+$ with no spaces (token characters only).
- Move localized or descriptive data into the header value, not the name.
- Strip BOM and trim names loaded from JSON/YAML config files.
When it happens
Trigger: Calling Builder.Header with a name containing spaces, tabs, non-ASCII (e.g. UTF-8 'X-Köln'), or control characters such as '\t' or NUL.
Common situations: Header names copied with a trailing space; localized header names; names read from JSON/config that include BOM or non-ASCII characters; accidental tab between name and value.
Related errors
- emlbuilder: header value contains dangerous Unicode characte
- emlbuilder: header name contains ':', CR, or LF: %q
- emlbuilder: display name contains CR or LF: %q
- emlbuilder: content ID contains control character: %q
- emlbuilder: From address is required
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/0db5268a70d93f17.
Report an issue: GitHub.