hashicorp/packer · error
Invalid remote protocol: %q, expected something like '%s.%s'
Error message
Invalid remote protocol: %q, expected something like '%s.%s'
What it means
NewAPIVersion() parses a remote protocol version string like "x5.0" into an APIVersion. After trimming the "x" prefix it requires at least two dot-separated components (major.minor). Strings with fewer parts cannot represent a valid protocol version and are rejected.
Source
Thrown at packer/plugin-getter/plugins.go:489
// ExpectedZipFilename is the filename of the zip we expect to find, the
// value is known only after parsing the checksum file file.
func (gp *GetOptions) ExpectedZipFilename() string {
return gp.expectedZipFilename
}
type APIVersion struct {
Major int
Minor int
}
func NewAPIVersion(apiVersion string) (APIVersion, error) {
ver := APIVersion{}
apiVersion = strings.TrimPrefix(strings.TrimSpace(apiVersion), "x")
parts := strings.Split(apiVersion, ".")
if len(parts) < 2 {
return ver, fmt.Errorf(
"Invalid remote protocol: %q, expected something like '%s.%s'",
apiVersion, pluginsdk.APIVersionMajor, pluginsdk.APIVersionMinor,
)
}
vMajor, err := strconv.Atoi(parts[0])
if err != nil {
return ver, err
}
ver.Major = vMajor
vMinor, err := strconv.Atoi(parts[1])
if err != nil {
return ver, err
}
ver.Minor = vMinor
return ver, nilView on GitHub (pinned to eb36e3c3e4)
Solutions
- Ensure the plugin binary/filename embeds a full x{major}.{minor} protocol version (e.g. x5.0); rebuild with the current packer-plugin-sdk.
- Fix the asset/checksum filename so the _x{M}.{N}_ segment is present and well-formed.
- Upgrade the plugin to a release produced by the standard SDK tooling.
Example fix
// before packer-plugin-foo_1.0.0_x5_linux_amd64.zip // after packer-plugin-foo_1.0.0_x5.0_linux_amd64.zip
Defensive patterns
Strategy: validation
Validate before calling
trimmed := strings.TrimPrefix(strings.TrimSpace(s), "x")
if len(strings.Split(trimmed, ".")) < 2 {
return fmt.Errorf("protocol version %q must be x{major}.{minor}", s)
} Type guard
func isCompleteProtVersion(s string) bool {
parts := strings.Split(strings.TrimPrefix(strings.TrimSpace(s), "x"), ".")
return len(parts) >= 2 && parts[0] != "" && parts[1] != ""
} Try / catch
av, err := NewAPIVersion(prot)
if err != nil {
if strings.Contains(err.Error(), "Invalid remote protocol") {
// treat asset/binary as produced by nonstandard tooling; skip it
}
} Prevention
- Ensure filenames embed the full _x{major}.{minor}_ segment
- Build plugins only with the current packer-plugin-sdk
- Reject or skip checksum entries failing a protocol-version regex precheck
When it happens
Trigger: Calling NewAPIVersion with a string like "5", "", "x", or "x5" — i.e. the protocol version advertised by a plugin binary or embedded in a filename lacks the major.minor form.
Common situations: A plugin built with a very old or custom SDK that reports a single-number protocol version; a corrupted plugin binary filename like foo_1.0.0_x5_linux_amd64 (missing minor); hand-edited checksum entries.
Related errors
- Failed to parse API Version from constraints: %s
- unsupported remote protocol MAJOR version %d. The current MA
- malformed filename expected %s{version}_x{protocol-version}_
- wrong version: %s does not match expected %s
- wrong system, expected %s_%s
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/eb56fa8b7354f7b8.
Report an issue: GitHub.