FiloSottile/age · error
failed to write error stanza: %v
Error message
failed to write error stanza: %v
What it means
writeError formats an error stanza (Type "error", with the error text as the body) and writes it to the plugin's stdout. This message wraps a failure of Stanza.Marshal on that write — i.e. the error stanza itself could not be serialized or written to stdout, typically due to an underlying I/O failure on the output pipe.
Source
Thrown at plugin/plugin.go:673
}
}
func expectUnsupported(sr *format.StanzaReader) error {
unsupported, err := sr.ReadStanza()
if err != nil {
return fmt.Errorf("failed to read unsupported stanza: %v", err)
}
if unsupported.Type != "unsupported" {
return fmt.Errorf("expected unsupported stanza, got %q", unsupported.Type)
}
return expectStanzaWithNoBody(unsupported, 0)
}
func (p *Plugin) writeError(args []string, err error) error {
s := &format.Stanza{Type: "error", Args: args}
s.Body = []byte(err.Error())
if err := s.Marshal(p.stdout); err != nil {
return fmt.Errorf("failed to write error stanza: %v", err)
}
if err := expectOk(p.sr); err != nil {
return fmt.Errorf("%v", err)
}
return nil
}
View on GitHub (pinned to b74dce4cdb)
Solutions
- Check the wrapped %v detail for the underlying write error (EPIPE, EBADF, etc.).
- Ensure the invoking age process keeps stdout/stdin pipes open for the plugin's lifetime.
- Verify the plugin is invoked as a plugin (with piped stdio), not run interactively with a closed stdout.
- Check disk space / file descriptor limits if stdout is redirected to a file.
Defensive patterns
Strategy: try-catch
Try / catch
if err := runPlugin(); err != nil {
var syscallErr *os.SyscallError
if errors.As(err, &syscallErr) && errors.Is(syscallErr.Err, syscall.EPIPE) {
// parent process gone; abort quietly
}
} Prevention
- Never close the age process's stdin/stdout pipes before the plugin finishes.
- Run plugins through the age binary rather than invoking them interactively.
- Monitor wrapped write errors (EPIPE/EBADF) to detect premature parent exit.
When it happens
Trigger: Plugin.IdentityV1, recipientError, or identityError call writeError when the original operation failed; the Marshal call to p.stdout then fails (broken/closed stdout pipe, output stream error).
Common situations: Parent age process closed its end of the pipe or crashed mid-protocol; stdout redirected to a full disk or closed file descriptor; running the plugin binary in an environment without a connected stdout.
Related errors
- non-EOF error reading after end of encrypted file: %w
- failed to read final chunk: %w
- failed to read chunk at offset %d: %w
- %s plugin: %w
- couldn't start plugin: %w
AI-assisted analysis of FiloSottile/age@b74dce4cdb (2026-08-31).
Data as JSON: /api/errors/6949ab89fe58aa8c.
Report an issue: GitHub.