{"record":{"id":"eb56fa8b7354f7b8","repo":"hashicorp/packer","slug":"invalid-remote-protocol-q-expected-something-li","errorCode":null,"errorMessage":"Invalid remote protocol: %q, expected something like '%s.%s'","messagePattern":"Invalid remote protocol: %q, expected something like '(.+?)\\.(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packer/plugin-getter/plugins.go","lineNumber":489,"sourceCode":"\n// ExpectedZipFilename is the filename of the zip we expect to find, the\n// value is known only after parsing the checksum file file.\nfunc (gp *GetOptions) ExpectedZipFilename() string {\n\treturn gp.expectedZipFilename\n}\n\ntype APIVersion struct {\n\tMajor int\n\tMinor int\n}\n\nfunc NewAPIVersion(apiVersion string) (APIVersion, error) {\n\tver := APIVersion{}\n\n\tapiVersion = strings.TrimPrefix(strings.TrimSpace(apiVersion), \"x\")\n\tparts := strings.Split(apiVersion, \".\")\n\tif len(parts) < 2 {\n\t\treturn ver, fmt.Errorf(\n\t\t\t\"Invalid remote protocol: %q, expected something like '%s.%s'\",\n\t\t\tapiVersion, pluginsdk.APIVersionMajor, pluginsdk.APIVersionMinor,\n\t\t)\n\t}\n\n\tvMajor, err := strconv.Atoi(parts[0])\n\tif err != nil {\n\t\treturn ver, err\n\t}\n\tver.Major = vMajor\n\n\tvMinor, err := strconv.Atoi(parts[1])\n\tif err != nil {\n\t\treturn ver, err\n\t}\n\tver.Minor = vMinor\n\n\treturn ver, nil","sourceCodeStart":471,"sourceCodeEnd":507,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/packer/plugin-getter/plugins.go#L471-L507","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\npacker-plugin-foo_1.0.0_x5_linux_amd64.zip\n// after\npacker-plugin-foo_1.0.0_x5.0_linux_amd64.zip","handlingStrategy":"validation","validationCode":"trimmed := strings.TrimPrefix(strings.TrimSpace(s), \"x\")\nif len(strings.Split(trimmed, \".\")) < 2 {\n\treturn fmt.Errorf(\"protocol version %q must be x{major}.{minor}\", s)\n}","typeGuard":"func isCompleteProtVersion(s string) bool {\n\tparts := strings.Split(strings.TrimPrefix(strings.TrimSpace(s), \"x\"), \".\")\n\treturn len(parts) >= 2 && parts[0] != \"\" && parts[1] != \"\"\n}","tryCatchPattern":"av, err := NewAPIVersion(prot)\nif err != nil {\n\tif strings.Contains(err.Error(), \"Invalid remote protocol\") {\n\t\t// treat asset/binary as produced by nonstandard tooling; skip it\n\t}\n}","preventionTips":["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"],"tags":["plugin-getter","protocol-version","parsing","plugin-install"],"backgroundTag":"invalid-version-string","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"}