{"record":{"id":"47862d4437f1c43c","repo":"FiloSottile/age","slug":"malformed-recipient-stanza-unexpected-index","errorCode":null,"errorMessage":"malformed recipient stanza: unexpected index","messagePattern":"malformed recipient stanza: unexpected index","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/client.go","lineNumber":125,"sourceCode":"ReadLoop:\n\tfor {\n\t\ts, err := r.ui.readStanza(r.name, sr)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\tswitch s.Type {\n\t\tcase \"recipient-stanza\":\n\t\t\tif len(s.Args) < 2 {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"malformed recipient stanza: unexpected argument count\")\n\t\t\t}\n\t\t\tn, err := strconv.Atoi(s.Args[0])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"malformed recipient stanza: invalid index\")\n\t\t\t}\n\t\t\t// We only send a single file key, so the index must be 0.\n\t\t\tif n != 0 {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"malformed recipient stanza: unexpected index\")\n\t\t\t}\n\n\t\t\tstanzas = append(stanzas, &age.Stanza{\n\t\t\t\tType: s.Args[1],\n\t\t\t\tArgs: s.Args[2:],\n\t\t\t\tBody: s.Body,\n\t\t\t})\n\n\t\t\tif err := writeStanza(conn, \"ok\"); err != nil {\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\t\tcase \"labels\":\n\t\t\tif labels != nil {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"repeated labels stanza\")\n\t\t\t}\n\t\t\tlabels = s.Args\n\n\t\t\tif err := writeStanza(conn, \"ok\"); err != nil {","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/FiloSottile/age/blob/b74dce4cdbe35b5e5f66c06d9612b72f89028758/plugin/client.go#L107-L143","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (plugin side)\nn := lastUsedIndex // stale state, e.g. 1\nwriteStanza(conn, \"recipient-stanza\", strconv.Itoa(n), stanzaType)\n// after\nwriteStanza(conn, \"recipient-stanza\", \"0\", stanzaType) // only one file key is sent","handlingStrategy":"validation","validationCode":"// Go: assert index 0 before accepting a stanza when only one file key is sent\nn, err := strconv.Atoi(args[0])\nif err == nil && n != 0 {\n    return fmt.Errorf(\"plugin returned stanza for unexpected file key index %d\", n)\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"unexpected index\") {\n        return fmt.Errorf(\"plugin state bug (non-zero stanza index); restart plugin process or upgrade: %w\", err)\n    }\n    return err\n}","preventionTips":["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."],"tags":["go","age","plugin","protocol","malformed-data"],"backgroundTag":"plugin-protocol-violation","analyzedSha":"b74dce4cdbe35b5e5f66c06d9612b72f89028758","analyzedAt":"2026-08-31T23:59:31.627Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}