pulumi/pulumi · error

invalid enforcement level %q

Error message

invalid enforcement level %q

What it means

When configuring a policy pack (ConfigureAnalyzer path), each policy config entry's EnforcementLevel is validated against apitype enforcement levels before being sent to the analyzer plugin. An unrecognized level string produces "invalid enforcement level %q".

Source

Thrown at sdk/go/common/resource/plugin/analyzer_plugin.go:624

	return PluginInfo{
		Version: version,
	}, nil
}

func (a *analyzer) Configure(ctx context.Context, policyConfig map[string]AnalyzerPolicyConfig) error {
	label := a.label() + ".Configure(...)"
	logging.V(7).Infof("%s executing", label)

	if len(policyConfig) == 0 {
		logging.V(7).Infof("%s returning early, no config specified", label)
		return nil
	}

	c := make(map[string]*pulumirpc.PolicyConfig)

	for k, v := range policyConfig {
		if !v.EnforcementLevel.IsValid() {
			return fmt.Errorf("invalid enforcement level %q", v.EnforcementLevel)
		}

		props, err := structpb.NewStruct(v.Properties)
		if err != nil {
			return fmt.Errorf("marshalling properties: %w", err)
		}

		c[k] = &pulumirpc.PolicyConfig{
			EnforcementLevel: marshalEnforcementLevel(v.EnforcementLevel),
			Properties:       props,
		}
	}

	_, err := a.client.Configure(ctx, &pulumirpc.ConfigureAnalyzerRequest{
		PolicyConfig: c,
	})
	if err != nil {
		rpcError := rpcerror.Convert(err)

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Use one of the exact valid values: advisory, mandatory, remediate, disabled (correct case) in the policy config source.
  2. Fix the enforcement level in PulumiPolicy.yaml or the --policy-config input rather than hand-editing serialized config.
  3. Validate config with `pulumi policy validate` or the pack's own linting before running.
  4. If the level comes from a newer CLI, upgrade the CLI/policy SDK so both recognize the value.

Example fix

// before
policyConfig["aws-s3-no-public-read"] = AnalyzerPolicyConfig{EnforcementLevel: apitype.EnforcementLevel("MANDATORY")}
// after
policyConfig["aws-s3-no-public-read"] = AnalyzerPolicyConfig{EnforcementLevel: apitype.Mandatory}
Defensive patterns

Strategy: validation

Validate before calling

// Go: validate enforcement levels before building policy config
valid := map[apitype.EnforcementLevel]bool{
    apitype.Advisory: true, apitype.Mandatory: true,
    apitype.Remediate: true, apitype.Disabled: true,
}
for k, v := range policyConfig {
    if !valid[v.EnforcementLevel] {
        return fmt.Errorf("policy %q: invalid enforcement level %q (use advisory|mandatory|remediate|disabled)", k, v.EnforcementLevel)
    }
}

Type guard

func isValidEnforcementLevel(l apitype.EnforcementLevel) bool {
    return l.IsValid()
}

Try / catch

if err := configureAnalyzer(policyConfig); err != nil {
    if strings.Contains(err.Error(), "invalid enforcement level") {
        // normalize: trim, lowercase, retry once
        return retryWithNormalizedLevels(policyConfig)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ConfigureAnalyzer with policyConfig map entries whose EnforcementLevel field holds a value not in {Advisory, Mandatory, Remediate, Disabled} (apitype.EnforcementLevel.IsValid() == false).

Common situations: Typo'd enforcement level in PulumiPolicy.yaml or CLI flags (e.g. "manditory", "advisory " with whitespace, lowercase "mandatory"); hand-edited policy config files; version drift where a level name was renamed.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/5ee24923d5715fce. Report an issue: GitHub.