FiloSottile/age · error
malformed recipient stanza: invalid index
Error message
malformed recipient stanza: invalid index
What it means
The plugin sent a recipient-stanza whose first argument (the file-key index) is not a valid decimal integer, so strconv.Atoi failed. The protocol requires Args[0] to be the numeric index of the wrapped file key; anything else is rejected as malformed.
Source
Thrown at plugin/client.go:121
}
// Phase 2: plugin responds with stanzas
sr := format.NewStanzaReader(bufio.NewReader(conn))
ReadLoop:
for {
s, err := r.ui.readStanza(r.name, sr)
if err != nil {
return nil, nil, err
}
switch s.Type {
case "recipient-stanza":
if len(s.Args) < 2 {
return nil, nil, fmt.Errorf("malformed recipient stanza: unexpected argument count")
}
n, err := strconv.Atoi(s.Args[0])
if err != nil {
return nil, nil, fmt.Errorf("malformed recipient stanza: invalid index")
}
// We only send a single file key, so the index must be 0.
if n != 0 {
return nil, nil, fmt.Errorf("malformed recipient stanza: unexpected index")
}
stanzas = append(stanzas, &age.Stanza{
Type: s.Args[1],
Args: s.Args[2:],
Body: s.Body,
})
if err := writeStanza(conn, "ok"); err != nil {
return nil, nil, err
}
case "labels":
if labels != nil {
return nil, nil, fmt.Errorf("repeated labels stanza")View on GitHub (pinned to b74dce4cdb)
Solutions
- Upgrade the plugin to a version matching the current recipient-v1 protocol (numeric index as first arg).
- Fix the plugin's stanza writer so Args[0] is the decimal file-key index ('0' for a single file key).
- Capture the raw stanza to verify the argument layout before filing a bug with the plugin author.
- Pin known-good plugin versions to avoid mixing protocol revisions.
Example fix
// before (plugin side) writeStanza(conn, "recipient-stanza", "x25519", body) // no index, type first // after writeStanza(conn, "recipient-stanza", "0", "x25519", body)
Defensive patterns
Strategy: validation
Validate before calling
// Go: ensure the index argument parses before use
if _, err := strconv.Atoi(args[0]); err != nil {
return fmt.Errorf("plugin sent non-numeric stanza index %q", args[0])
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "invalid index") {
return fmt.Errorf("plugin protocol mismatch (missing numeric index); upgrade plugin: %w", err)
}
return err
} Prevention
- Write plugin stanzas with the numeric index as the first argument.
- Run integration tests between your plugin and the age client after every protocol change.
- Version-check the plugin binary at startup if possible.
- Report non-conformant plugins upstream rather than working around them.
When it happens
Trigger: WrapWithLabels/Wrap receives a recipient-stanza where Args[0] is a non-numeric string, e.g. the plugin omitted the index or put the stanza type first.
Common situations: Old or non-conformant plugin versions that send stanzas without the leading index; a plugin written against a different protocol revision; argument ordering bugs in a plugin under development.
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
- malformed recipient stanza: unexpected argument count
- malformed recipient stanza: unexpected index
- repeated labels stanza
- %s
- received zero recipient stanzas
AI-assisted analysis of FiloSottile/age@b74dce4cdb (2026-08-31).
Data as JSON: /api/errors/a75fb8621d6d4e44.
Report an issue: GitHub.