FiloSottile/age · error

invalid stanza argument: %q

Error message

invalid stanza argument: %q

What it means

Same validation as the Type, applied to each element of Stanza.Args: args must be single-line printable-ASCII strings without spaces, because args are space-separated on one line of the age wire format. Marshal aborts before writing anything if an argument is invalid.

Source

Thrown at internal/format/format.go:117

// because no input was written, or because a multiple of BytesPerLine was.
//
// Calling LastLineIsEmpty before Close is meaningless.
func (w *WrappedBase64Encoder) LastLineIsEmpty() bool {
	return w.written%ColumnsPerLine == 0
}

const intro = "age-encryption.org/v1\n"

var stanzaPrefix = []byte("->")
var footerPrefix = []byte("---")

func (r *Stanza) Marshal(w io.Writer) error {
	if !isValidString(r.Type) {
		return fmt.Errorf("invalid stanza type: %q", r.Type)
	}
	for _, a := range r.Args {
		if !isValidString(a) {
			return fmt.Errorf("invalid stanza argument: %q", a)
		}
	}
	if _, err := w.Write(stanzaPrefix); err != nil {
		return err
	}
	if _, err := io.WriteString(w, " "+r.Type); err != nil {
		return err
	}
	for _, a := range r.Args {
		if _, err := io.WriteString(w, " "+a); err != nil {
			return err
		}
	}
	if _, err := io.WriteString(w, "\n"); err != nil {
		return err
	}
	ww := NewWrappedBase64Encoder(b64, w)
	if _, err := ww.Write(r.Body); err != nil {

View on GitHub (pinned to b74dce4cdb)

Solutions

  1. Base64-encode arbitrary bytes before placing them in Args
  2. Trim newlines/whitespace from each arg and re-check
  3. Identify the bad arg via the %q message and fix its producer

Example fix

// before
args := []string{string(rawBody)}
// after
args := []string{base64.RawStdEncoding.EncodeToString(rawBody)}
Defensive patterns

Strategy: validation

Validate before calling

for _, a := range args {
    for _, c := range a {
        if c <= 32 || c > 126 { return errors.New("stanza arg contains invalid character") }
    }
}

Type guard

func isArgSafe(a string) bool {
    return a != "" && strings.IndexFunc(a, func(r rune) bool { return r <= 32 || r > 126 }) < 0
}

Prevention

When it happens

Trigger: Marshal a Stanza whose Args include a value with a space, newline, tab, or non-ASCII/control byte — e.g. base64 padded data accidentally containing '='? (= is fine) — more commonly raw binary or CRLF-terminated values passed as args.

Common situations: Plugin authors passing binary or multiline payloads as stanza args instead of base64-encoding them; values read from a file with trailing newline.

Related errors


AI-assisted analysis of FiloSottile/age@b74dce4cdb (2026-08-31). Data as JSON: /api/errors/6f5b3f0f50b6ac5a. Report an issue: GitHub.