{"record":{"id":"81a86f99a25e6861","repo":"hashicorp/packer","slug":"malformed-filename-expected-s-version-x-protocol","errorCode":null,"errorMessage":"malformed filename expected %s{version}_x{protocol-version}_{os}_{arch}","messagePattern":"malformed filename expected (.+?)(.+?)_x(.+?)_(.+?)_(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packer/plugin-getter/github/getter.go","lineNumber":313,"sourceCode":"}\n\n// Init method: a file inside will look like so:\n//\n//\tpacker-plugin-comment_v0.2.12_x5.0_freebsd_amd64.zip\nfunc (g *Getter) Init(req *plugingetter.Requirement, entry *plugingetter.ChecksumFileEntry) error {\n\tfilename := entry.Filename\n\tres := strings.TrimPrefix(filename, req.FilenamePrefix())\n\t// res now looks like v0.2.12_x5.0_freebsd_amd64.zip\n\n\tentry.Ext = filepath.Ext(res)\n\n\tres = strings.TrimSuffix(res, entry.Ext)\n\t// res now looks like v0.2.12_x5.0_freebsd_amd64\n\n\tparts := strings.Split(res, \"_\")\n\t// [\"v0.2.12\", \"x5.0\", \"freebsd\", \"amd64\"]\n\tif len(parts) < 4 {\n\t\treturn fmt.Errorf(\"malformed filename expected %s{version}_x{protocol-version}_{os}_{arch}\", req.FilenamePrefix())\n\t}\n\n\tentry.BinVersion, entry.ProtVersion, entry.Os, entry.Arch = parts[0], parts[1], parts[2], parts[3]\n\n\treturn nil\n}\n\nfunc (g *Getter) Validate(opt plugingetter.GetOptions, expectedVersion string, installOpts plugingetter.BinaryInstallationOptions, entry *plugingetter.ChecksumFileEntry) error {\n\texpectedBinVersion := \"v\" + expectedVersion\n\tif entry.BinVersion != expectedBinVersion {\n\t\treturn fmt.Errorf(\"wrong version: %s does not match expected %s\", entry.BinVersion, expectedBinVersion)\n\t}\n\tif entry.Os != installOpts.OS || entry.Arch != installOpts.ARCH {\n\t\treturn fmt.Errorf(\"wrong system, expected %s_%s\", installOpts.OS, installOpts.ARCH)\n\t}\n\n\treturn installOpts.CheckProtocolVersion(entry.ProtVersion)\n}","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/packer/plugin-getter/github/getter.go#L295-L331","documentation":"Init() parses a checksum-file entry filename into its components (binary version, protocol version, OS, arch) after stripping the prefix and extension. The remaining name must have at least 4 underscore-separated parts shaped like {prefix}vX.Y.Z_xM.N_os_arch. Fewer parts means the filename does not follow the Packer plugin binary naming convention.","triggerScenarios":"Getter.Init() receives a ChecksumFileEntry whose filename, after trimming the prefix (e.g. packer-plugin-), extension (.zip), and splitting on \"_\", yields fewer than 4 parts — e.g. \"packer-plugin-name_v1.0.0.zip\" with no _x5.0_linux_amd64 suffix.","commonSituations":"A hand-rolled or renamed release asset in a GitHub checksums file; a plugin release built with an old or nonstandard naming scheme; a custom/renamed plugin published outside the SDK's naming tooling; corrupted or edited SHA256SUM files.","solutions":["Rename the release asset to the standard form: packer-plugin-<name>_<version>_x<protocol>_<os>_<arch>.zip and regenerate the SHA256SUM file.","Rebuild the plugin release with the current packer-plugin-sdk (go build via the SDK scaffolding) so the filename embeds version, protocol, OS, and arch.","Verify the checksums file on the release matches the actual asset names."],"exampleFix":"// before (asset name)\npacker-plugin-foo_1.0.0.zip\n// after\npacker-plugin-foo_1.0.0_x5.0_linux_amd64.zip","handlingStrategy":"validation","validationCode":"base := strings.TrimSuffix(strings.TrimPrefix(fname, prefix), ext)\nparts := strings.Split(base, \"_\")\nif len(parts) < 4 {\n\treturn fmt.Errorf(\"asset %q does not match {version}_x{proto}_{os}_{arch}\", fname)\n}","typeGuard":"func isWellFormedPluginAsset(fname, prefix, ext string) bool {\n\tparts := strings.Split(strings.TrimSuffix(strings.TrimPrefix(fname, prefix), ext), \"_\")\n\treturn len(parts) >= 4 && strings.HasPrefix(parts[1], \"x\")\n}","tryCatchPattern":"if err := getter.Init(req, entries); err != nil {\n\tif strings.Contains(err.Error(), \"malformed filename\") {\n\t\tlog.Printf(\"skipping nonstandard asset: %v\", err)\n\t}\n}","preventionTips":["Publish release assets built by the standard packer-plugin-sdk tooling","Never rename plugin zips by hand","Regenerate the SHA256SUM file whenever asset names change"],"tags":["plugin-getter","filename-parsing","plugin-install","github"],"backgroundTag":"malformed-filename","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"}