{"record":{"id":"5b56abb9848110fd","repo":"hashicorp/packer","slug":"listinstallations-failed-to-list-installed-plugin","errorCode":null,"errorMessage":"ListInstallations: failed to list installed plugins: %s","messagePattern":"ListInstallations: failed to list installed plugins: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packer/plugin-getter/plugins.go","lineNumber":228,"sourceCode":"\n\treturn retMatches, err\n}\n\n// ListInstallations lists unique installed versions of plugin Requirement pr\n// with opts as a filter.\n//\n// Installations are sorted by version and one binary per version is returned.\n// Last binary detected takes precedence: in the order 'FromFolders' option.\n//\n// At least one opts.Checksumers must be given for a binary to be even\n// considered.\nfunc (pr Requirement) ListInstallations(opts ListInstallationsOptions) (InstallList, error) {\n\tres := InstallList{}\n\tlog.Printf(\"[TRACE] listing potential installations for %q that match %q. %#v\", pr.Identifier, pr.VersionConstraints, opts)\n\n\tmatches, err := pr.getPluginBinaries(opts)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"ListInstallations: failed to list installed plugins: %s\", err)\n\t}\n\n\tfor _, path := range matches {\n\t\tfname := filepath.Base(path)\n\t\tif fname == \".\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tchecksumOk := false\n\t\tfor _, checksummer := range opts.Checksummers {\n\n\t\t\tcs, err := checksummer.GetCacheChecksumOfFile(path)\n\t\t\tif err != nil {\n\t\t\t\tlog.Printf(\"[TRACE] GetChecksumOfFile(%q) failed: %v\", path, err)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif err := checksummer.ChecksumFile(cs, path); err != nil {","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/packer/plugin-getter/plugins.go#L210-L246","documentation":"Requirement.ListInstallations() wraps any failure from getPluginBinaries() (which globs the plugin directories for installed binaries) with this prefixed message. The underlying error is a filesystem/glob problem, not a plugin problem — Packer could not enumerate what is installed.","triggerScenarios":"Calling ListInstallations when pr.getPluginBinaries(opts) fails: the plugin directory path is unreadable, a glob pattern is invalid, or an I/O error occurs while walking ~/.packer.d/plugins/... (often because opts.FromFolders or env-configured paths point somewhere inaccessible).","commonSituations":"PACKER_PLUGIN_PATH points to a nonexistent or permission-restricted directory; home directory redirection (HOME/XDG) wrong in CI containers; a path that is a file rather than a directory.","solutions":["Inspect the wrapped inner error (%s) to identify the failing path, then verify that directory exists and is readable (ls the PACKER_PLUGIN_PATH / ~/.packer.d/plugins tree).","Fix the environment: set PACKER_PLUGIN_PATH or HOME/XDG_CONFIG_HOME to a valid, accessible directory.","Recreate the plugin directory with correct permissions, then retry the packer command."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"for _, dir := range opts.FromFolders {\n\tif fi, err := os.Stat(dir); err != nil || !fi.IsDir() {\n\t\treturn fmt.Errorf(\"plugin dir %q missing or not a directory\", dir)\n\t}\n}","typeGuard":null,"tryCatchPattern":"installs, err := req.ListInstallations(opts)\nif err != nil {\n\treturn fmt.Errorf(\"%v: check PACKER_PLUGIN_PATH and %s are readable\", err, defaultPluginDir)\n}","preventionTips":["Verify PACKER_PLUGIN_PATH/HOME point to accessible directories before running packer","Ensure plugin directories exist with correct permissions in CI images","Log the resolved plugin directory at debug level during setup"],"tags":["plugin-getter","filesystem","plugin-install","directory"],"backgroundTag":"plugin-directory-unreadable","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}