FiloSottile/age · error
malformed recipient stanza: unexpected index
Error message
malformed recipient stanza: unexpected index
What it means
The plugin sent a recipient-stanza with a valid numeric index, but the index is not 0. The client sends only a single file key to the plugin, so any stanza claiming to wrap a different file key index is invalid and rejected.
Source
Thrown at plugin/client.go:125
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")
}
labels = s.Args
if err := writeStanza(conn, "ok"); err != nil {View on GitHub (pinned to b74dce4cdb)
Solutions
- Upgrade or fix the plugin so every returned recipient-stanza uses index 0.
- Clear any plugin-side caching that could carry stanza indices between wrap sessions.
- Capture the offending stanza and file a bug with the plugin maintainer.
- Retry with a fresh plugin process to rule out stale state.
Example fix
// before (plugin side) n := lastUsedIndex // stale state, e.g. 1 writeStanza(conn, "recipient-stanza", strconv.Itoa(n), stanzaType) // after writeStanza(conn, "recipient-stanza", "0", stanzaType) // only one file key is sent
Defensive patterns
Strategy: validation
Validate before calling
// Go: assert index 0 before accepting a stanza when only one file key is sent
n, err := strconv.Atoi(args[0])
if err == nil && n != 0 {
return fmt.Errorf("plugin returned stanza for unexpected file key index %d", n)
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "unexpected index") {
return fmt.Errorf("plugin state bug (non-zero stanza index); restart plugin process or upgrade: %w", err)
}
return err
} Prevention
- Never cache stanza indices across wrap sessions in plugin code.
- Always emit index 0 when the client sends a single file key.
- Restart plugin processes between sessions to avoid stale state.
- Add a test in the plugin asserting all emitted indices are 0.
When it happens
Trigger: WrapWithLabels/Wrap receives a recipient-stanza whose parsed index n is nonzero, meaning the plugin claims to wrap a file key other than the one sent, indicating a protocol/state bug in the plugin.
Common situations: A plugin that echoes cached stanzas from a previous session; a plugin that enumerates multiple file keys incorrectly; a buggy third-party plugin reusing stanza code across sessions.
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: invalid index
- repeated labels stanza
- %s
- received zero recipient stanzas
AI-assisted analysis of FiloSottile/age@b74dce4cdb (2026-08-31).
Data as JSON: /api/errors/47862d4437f1c43c.
Report an issue: GitHub.