hashicorp/terraform · error
action %s has config values with unsupported marks: %v
Error message
action %s has config values with unsupported marks: %v
What it means
After stripping both sensitive and ephemeral marks from the action config value, any remaining marks are unrecognized by the renderer. Only those two mark kinds are handled, so leftover marks indicate a mark type the JSON format cannot faithfully represent, and serialization is aborted.
Source
Thrown at internal/command/jsonplan/action_invocations.go:165
ai.InvokeActionTrigger.CallingResourceAddress = at.CallingResourceAddr.String()
}
default:
return ai, fmt.Errorf("unsupported action trigger type: %T", at)
}
var config []byte
var sensitive []byte
var unknown []byte
if actionDec.ConfigValue != cty.NilVal {
unmarkedValue, pvms := actionDec.ConfigValue.UnmarkDeepWithPaths()
sensitivePaths, otherMarks := marks.PathsWithMark(pvms, marks.Sensitive)
ephemeralPaths, otherMarks := marks.PathsWithMark(otherMarks, marks.Ephemeral)
if len(ephemeralPaths) > 0 {
return ai, fmt.Errorf("action %s has ephemeral config values, which are not supported in action invocations", action.Addr)
}
if len(otherMarks) > 0 {
return ai, fmt.Errorf("action %s has config values with unsupported marks: %v", action.Addr, otherMarks)
}
unknownValue := unknownAsBool(unmarkedValue)
unknown, err = ctyjson.Marshal(unknownValue, unknownValue.Type())
if err != nil {
return ai, err
}
configValue := omitUnknowns(unmarkedValue)
config, err = ctyjson.Marshal(configValue, configValue.Type())
if err != nil {
return ai, err
}
sensitivePaths = append(sensitivePaths, schema.ConfigSchema.SensitivePaths(unmarkedValue, nil)...)
cs := jsonstate.SensitiveAsBool(marks.MarkPaths(unmarkedValue, marks.Sensitive, sensitivePaths))
sensitive, err = ctyjson.Marshal(cs, cs.Type())
if err != nil {View on GitHub (pinned to c9def3e214)
Solutions
- Inspect the %v output to identify which mark is present, then strip it before marshaling or add a handler in action_invocations.go:159.
- Use a Terraform build consistent with the plan artifact (no version skew).
- Report as a bug if the mark is a standard Terraform mark the renderer should support.
Defensive patterns
Strategy: validation
Validate before calling
// After stripping sensitive and ephemeral, fail fast on any remaining mark.
for _, a := range plan.Changes.ActionInvocations {
sch := schemas.ActionTypeConfig(a.ProviderAddr.Provider, a.Addr.Action.Action.Type)
dec, err := a.Decode(&sch)
if err != nil || dec.ConfigValue == cty.NilVal {
continue
}
unmarked, pvms := dec.ConfigValue.UnmarkDeepWithPaths()
_, other := marks.PathsWithMark(pvms, marks.Sensitive)
_, other = marks.PathsWithMark(other, marks.Ephemeral)
if len(other) > 0 {
return fmt.Errorf("action %s carries unsupported marks: %v", a.Addr, other)
}
_ = unmarked
} Prevention
- Avoid applying custom cty marks to values that flow into action config.
- Keep plan producers and consumers on the same Terraform version so the mark vocabulary matches.
- If you maintain a fork adding a mark, handle it in action_invocations.go:159.
When it happens
Trigger: len(otherMarks) > 0 after marks.PathsWithMark(pvms, marks.Sensitive) and then marks.PathsWithMark(otherMarks, marks.Ephemeral). A custom or newly introduced cty mark is attached to the decoded ConfigValue.
Common situations: A custom Terraform fork adding a new mark kind; a plan from a newer version that introduced a mark this binary does not know about; experimental/internal marks leaking into action config.
Related errors
- unsupported action trigger type: %T
- action %s has ephemeral config values, which are not support
- at most 1 action can be invoked per operation
- expected on 1 response value, got: %d
- failed to store state MD5: %w
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/8e8be1ff7ec0d0a1.
Report an issue: GitHub.