FiloSottile/age · error
repeated labels stanza
Error message
repeated labels stanza
What it means
The plugin sent more than one 'labels' stanza during the wrap protocol. A plugin must emit at most one labels stanza describing its supported labels, so a second one is a protocol violation and the client aborts.
Source
Thrown at plugin/client.go:139
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 {
return nil, nil, err
}
case "error":
if err := writeStanza(conn, "ok"); err != nil {
return nil, nil, err
}
return nil, nil, fmt.Errorf("%s", s.Body)
case "done":
break ReadLoop
default:
if ok, err := r.ui.handle(r.name, conn, s); err != nil {
return nil, nil, err
} else if !ok {View on GitHub (pinned to b74dce4cdb)
Solutions
- If you develop the plugin, emit the labels stanza exactly once, outside any per-stanza loop.
- Upgrade the plugin to the latest version where the duplicate-labels bug is fixed.
- Capture the plugin transcript to confirm which code path sends labels twice.
- Report the bug to the plugin maintainer if it is not your code.
Example fix
// before (plugin side, buggy)
for _, st := range stanzas {
writeStanza(conn, "recipient-stanza", "0", st.Type, st.Args...)
writeStanza(conn, "labels", "post-quantum") // emitted each iteration
}
// after
for _, st := range stanzas {
writeStanza(conn, "recipient-stanza", "0", st.Type, st.Args...)
}
writeStanza(conn, "labels", "post-quantum") // once Defensive patterns
Strategy: validation
Validate before calling
// Go (plugin side): emit labels exactly once
type labelsWriter struct{ sent bool }
func (w *labelsWriter) writeLabels(conn io.Writer, labels ...string) error {
if w.sent { return fmt.Errorf("labels already sent") }
w.sent = true
return writeStanza(conn, "labels", labels...)
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "repeated labels stanza") {
return fmt.Errorf("plugin bug: duplicate labels stanza; upgrade plugin: %w", err)
}
return err
} Prevention
- Emit the labels stanza once per session, outside any per-stanza loop.
- Track a 'labels sent' flag in plugin code.
- Test plugins end-to-end against the reference age client.
- Upgrade plugins that predate the labels protocol rules.
When it happens
Trigger: Calling WrapWithLabels/Wrap with a plugin that sends duplicate 'labels' stanzas in response to the file key, e.g. a buggy plugin loop that emits labels once per stanza instead of once per session.
Common situations: Developing a custom plugin and emitting labels inside a per-stanza loop; a plugin version bug where labels are re-sent after an 'ok'; misbehaving third-party plugins.
Related errors
- malformed recipient stanza: unexpected argument count
- malformed recipient stanza: invalid index
- malformed recipient stanza: unexpected index
- %s
- received zero recipient stanzas
AI-assisted analysis of FiloSottile/age@b74dce4cdb (2026-08-31).
Data as JSON: /api/errors/be478cac53cf488b.
Report an issue: GitHub.