FiloSottile/age · error

malformed file-key stanza: invalid index

Error message

malformed file-key stanza: invalid index

What it means

The client received a file-key stanza whose single argument could not be parsed as an integer index (strconv.Atoi failed). The plugin protocol requires the argument to be a decimal file index, so non-numeric content is rejected as malformed.

Source

Thrown at plugin/client.go:274

	}

	// Phase 2: plugin responds with various commands and a file key
	sr := format.NewStanzaReader(bufio.NewReader(conn))
ReadLoop:
	for {
		s, err := i.ui.readStanza(i.name, sr)
		if err != nil {
			return nil, err
		}

		switch s.Type {
		case "file-key":
			if len(s.Args) != 1 {
				return nil, fmt.Errorf("malformed file-key stanza: unexpected arguments count")
			}
			n, err := strconv.Atoi(s.Args[0])
			if err != nil {
				return nil, fmt.Errorf("malformed file-key stanza: invalid index")
			}
			// We only send a single file key, so the index must be 0.
			if n != 0 {
				return nil, fmt.Errorf("malformed file-key stanza: unexpected index")
			}
			if fileKey != nil {
				return nil, fmt.Errorf("received duplicated file-key stanza")
			}

			fileKey = s.Body

			if err := writeStanza(conn, "ok"); err != nil {
				return nil, err
			}
		case "error":
			if err := writeStanza(conn, "ok"); err != nil {
				return nil, err
			}

View on GitHub (pinned to b74dce4cdb)

Solutions

  1. Update/fix the plugin so it emits the numeric index, e.g. writeStanza(w, "file-key", "0")
  2. Run the plugin binary manually with --age-plugin=identity-v1 to inspect what it actually prints
  3. Check the plugin's stderr/log for a crash that garbled its stanza output

Example fix

// before (plugin side)
writeStanza(w, "file-key", idxLabel)
// after
writeStanza(w, "file-key", strconv.Itoa(idx))
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check plugin behavior by running it in a harness before production use
cmd := exec.Command("age-plugin-x", "--age-plugin=identity-v1")

Try / catch

_, err := identity.Unwrap(...)
if err != nil && strings.Contains(err.Error(), "malformed file-key stanza: invalid index") {
    return fmt.Errorf("plugin %s emitted non-numeric file-key index; upgrade plugin", pluginName)
}

Prevention

When it happens

Trigger: A plugin sends "file-key" with an argument that is not a decimal number (e.g. empty string, "abc", hex "0x0", whitespace-padded value) during Unwrap.

Common situations: Plugin implementations that format the index incorrectly (e.g. via fmt.Sprintf with %v on a non-int, or concatenating labels into the argument); corrupted or truncated pipe output from a failing plugin process.

Understand the failure class

Related errors


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