hashicorp/packer · error

unsupported format: %s (supported: cyclonedx, spdx)

Error message

unsupported format: %s (supported: cyclonedx, spdx)

What it means

encodeToFormat switches on g.config.Format and only supports "cyclonedx" and "spdx". Any other value falls into the default branch and returns "unsupported format: %s (supported: cyclonedx, spdx)". It is a straightforward configuration validation error naming the valid alternatives.

Source

Thrown at internal/sbom/generator_syft.go:87

		)
		if err != nil {
			return nil, fmt.Errorf("failed to create CycloneDX encoder: %w", err)
		}
		return format.Encode(*sbomData, encoder)

	case FormatSPDX:
		cfg := spdxjson.DefaultEncoderConfig()
		cfg.Pretty = true
		encoder, err := spdxjson.NewFormatEncoderWithConfig(
			cfg,
		)
		if err != nil {
			return nil, fmt.Errorf("failed to create SPDX encoder: %w", err)
		}
		return format.Encode(*sbomData, encoder)

	default:
		return nil, fmt.Errorf("unsupported format: %s (supported: cyclonedx, spdx)", g.config.Format)
	}
}

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Set config.Format to exactly "cyclonedx" or "spdx" (lowercase)
  2. Trim and lowercase user-supplied format values before constructing the Generator config
  3. Add an upfront validation in the config Prepare step to reject invalid formats with a friendly message
  4. If you need another syft format (e.g. spdx-tag-value), extend encodeToFormat with a new case and constant

Example fix

// before
format := cfg["format"] // "SPDX-JSON"
g, _ := NewGenerator(Config{Format: format})
// after
format := strings.ToLower(strings.TrimSpace(cfg["format"]))
if format != FormatCycloneDX && format != FormatSPDX {
    return fmt.Errorf("invalid sbom format %q; must be cyclonedx or spdx", format)
}
g, _ := NewGenerator(Config{Format: format})
Defensive patterns

Strategy: validation

Validate before calling

func validateFormat(f string) error {
    if f != "cyclonedx" && f != "spdx" {
        return fmt.Errorf("format %q must be exactly \"cyclonedx\" or \"spdx\"", f)
    }
    return nil
}

Type guard

func isSupportedFormat(f string) bool {
    return f == FormatCycloneDX || f == FormatSPDX
}

Try / catch

out, err := gen.Generate(ctx)
if err != nil {
    var unsupportedErr = "unsupported format"
    if strings.Contains(err.Error(), unsupportedErr) {
        return fmt.Errorf("bad sbom format config; use cyclonedx or spdx: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Setting the generator's Format config to any string other than "cyclonedx" or "spdx" (e.g. "json", "cyclonedx-json", "SPDX", or a typo) before calling Generate — the switch is case-sensitive and exact-match.

Common situations: Typos or wrong casing in a Packer template/plugin config field; users copying syft CLI format names ("syft-json", "spdx-json") which differ from the accepted constants; leaving an empty string when the code does not default it.

Related errors


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