hashicorp/packer · error

Multiple paths are no longer supported for PACKER_PLUGIN_PAT

Error message

Multiple paths are no longer supported for PACKER_PLUGIN_PATH.
This should be defined as one of the following options for your environment:
* PACKER_PLUGIN_PATH=%v

What it means

PACKER_PLUGIN_PATH must point to a single plugin directory. Multi-path (colon/semicolon-separated) values were supported in old Packer versions but are no longer allowed, so PluginFolder returns this error when the env var contains the OS path list separator.

Source

Thrown at packer/plugin_folders.go:22

package packer

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/hashicorp/packer-plugin-sdk/pathing"
)

var pathSep = fmt.Sprintf("%c", os.PathListSeparator)

// PluginFolder returns the known plugin folder based on system.
func PluginFolder() (string, error) {
	if packerPluginPath := os.Getenv("PACKER_PLUGIN_PATH"); packerPluginPath != "" {
		if strings.Contains(packerPluginPath, pathSep) {
			return "", fmt.Errorf("Multiple paths are no longer supported for PACKER_PLUGIN_PATH.\n"+
				"This should be defined as one of the following options for your environment:"+
				"\n* PACKER_PLUGIN_PATH=%v", strings.Join(strings.Split(packerPluginPath, pathSep), "\n* PACKER_PLUGIN_PATH="))
		}

		return packerPluginPath, nil
	}

	cd, err := pathing.ConfigDir()
	if err != nil {
		log.Printf("[ERR] Error loading config directory: %v", err)
		return "", err
	}

	return filepath.Join(cd, "plugins"), nil
}

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Set PACKER_PLUGIN_PATH to a single directory and place all plugins there.
  2. Remove the env var entirely to use the default per-user plugin directory.
  3. Split usage: keep one directory and symlink plugins from other locations into it.

Example fix

// before
export PACKER_PLUGIN_PATH=/opt/plugins:$HOME/.packer.d/plugins
// after
export PACKER_PLUGIN_PATH=$HOME/.packer.d/plugins
# or remove it and let Packer use its default discovery paths
Defensive patterns

Strategy: validation

Validate before calling

if v := os.Getenv("PACKER_PLUGIN_PATH"); strings.Contains(v, string(os.PathListSeparator)) {
  return fmt.Errorf("PACKER_PLUGIN_PATH must be a single directory, got %q", v)
}

Try / catch

if dir, err := packer.PluginFolder(); err != nil {
  if strings.Contains(err.Error(), "Multiple paths") {
    // reset PACKER_PLUGIN_PATH to one directory
  }
}

Prevention

When it happens

Trigger: PluginFolder() in packer/plugin_folders.go detects strings.Contains(envValue, os.PathListSeparator) — e.g. PACKER_PLUGIN_PATH=/opt/plugins:/home/user/plugins (unix) or C:\a;C:\b (windows). Callers include pluginDirectory, RunContext, loadConfig, and Discover.

Common situations: Reusing an old script that set multiple paths when Packer supported them; copying a PATH-style export to PACKER_PLUGIN_PATH; CI configuration combining custom and default plugin dirs.

Understand the failure class

Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/1360c8223decb077. Report an issue: GitHub.