{"record":{"id":"23b7abb5319d060d","repo":"FiloSottile/age","slug":"couldn-t-start-plugin-w","errorCode":null,"errorMessage":"couldn't start plugin: %w","messagePattern":"couldn't start plugin: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/client.go","lineNumber":80,"sourceCode":"\t}\n\treturn r.encoding\n}\n\nfunc (r *Recipient) Wrap(fileKey []byte) (stanzas []*age.Stanza, err error) {\n\tstanzas, _, err = r.WrapWithLabels(fileKey)\n\treturn\n}\n\nfunc (r *Recipient) WrapWithLabels(fileKey []byte) (stanzas []*age.Stanza, labels []string, err error) {\n\tdefer func() {\n\t\tif err != nil {\n\t\t\terr = fmt.Errorf(\"%s plugin: %w\", r.name, err)\n\t\t}\n\t}()\n\n\tconn, err := openClientConnection(r.name, \"recipient-v1\")\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"couldn't start plugin: %w\", err)\n\t}\n\tdefer conn.Close()\n\n\t// Phase 1: client sends recipient or identity and file key\n\taddType := \"add-recipient\"\n\tif r.identity {\n\t\taddType = \"add-identity\"\n\t}\n\tif err := writeStanza(conn, addType, r.encoding); err != nil {\n\t\treturn nil, nil, err\n\t}\n\tif _, err := writeGrease(conn); err != nil {\n\t\treturn nil, nil, err\n\t}\n\tif err := writeStanzaWithBody(conn, \"wrap-file-key\", fileKey); err != nil {\n\t\treturn nil, nil, err\n\t}\n\tif err := writeStanza(conn, \"extension-labels\"); err != nil {","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/FiloSottile/age/blob/b74dce4cdbe35b5e5f66c06d9612b72f89028758/plugin/client.go#L62-L98","documentation":"This error is returned by the plugin client's Wrap/WrapWithLabels function when it cannot open a connection to the plugin's helper binary via openClientConnection for the 'recipient-v1' protocol. The underlying cause (exec failure, handshake failure, etc.) is wrapped with %w. It means the age plugin process could not be launched or the client could not speak the v1 recipient protocol with it.","triggerScenarios":"Calling WrapWithLabels/Wrap (via age.Encrypt with a plugin recipient like age1yubikey1...) when the plugin binary named by the recipient prefix is not installed, not on PATH, not executable, or exits before completing the 'recipient-v1' handshake.","commonSituations":"Plugin not installed (e.g. age-plugin-yubikey missing from PATH); wrong recipient prefix so the client execs a nonexistent binary; plugin binary lacks execute permission; plugin built for another platform; plugin crashes at startup because hardware/agent is missing (YubiKey unplugged, yubikey-agent not running).","solutions":["Install the plugin binary matching the recipient prefix and ensure it is on PATH and executable.","Test the plugin manually (run its CLI) to confirm it starts.","Verify the recipient string prefix maps to the correct plugin name (age1yubikey1... -> age-plugin-yubikey).","Inspect the wrapped %w error for the OS-level cause (exec: not found, permission denied, exec format error) and fix accordingly.","If the plugin needs hardware/agent access, ensure the device or agent is available before encrypting."],"exampleFix":"// before\nrecipient, _ := age.ParseRecipients(\"age1yubikey1q...\") // plugin not installed\nout, err := age.Wrap(...) // fails: couldn't start plugin: exec not found\n// after\nif _, err := exec.LookPath(\"age-plugin-yubikey\"); err != nil {\n    return fmt.Errorf(\"install age-plugin-yubikey first: %w\", err)\n}\nout, err := age.Wrap(...)","handlingStrategy":"try-catch","validationCode":"// Go: check plugin availability before encryption\nif _, err := exec.LookPath(\"age-plugin-yubikey\"); err != nil {\n    return fmt.Errorf(\"plugin not installed or not on PATH: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"stanzas, labels, err := client.WrapWithLabels(fileKey)\nif err != nil {\n    var execErr *exec.Error\n    if errors.As(err, &execErr) {\n        return fmt.Errorf(\"plugin %q not installed: %w\", execErr.Name, err)\n    }\n    return err\n}","preventionTips":["Install the plugin binary and verify it is on PATH before encrypting.","Check exec.LookPath at application startup and fail fast with a clear message.","Pin plugin versions alongside your age library version.","Document plugin prerequisites (PATH, hardware/agent) for deployment environments like CI."],"tags":["go","age","plugin","process-exec","path"],"backgroundTag":"plugin-binary-not-found","analyzedSha":"b74dce4cdbe35b5e5f66c06d9612b72f89028758","analyzedAt":"2026-08-31T23:59:31.627Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}