hashicorp/terraform · error

action has ephemeral config values, which are not supported…

Error message

action %s has ephemeral config values, which are not supported in action invocations

What it means

Action invocation config contains ephemeral marks. Ephemeral values are intentionally non-serializable, so the plan JSON renderer refuses to embed them in an action invocation's config.

Solutions

  1. Remove ephemeral inputs from the action invocation config; pass non-ephemeral values instead.
  2. Wait for / upgrade to a Terraform version that supports ephemeral config in action invocations.
  3. If marks are unexpected, trace where the ephemeral mark was applied — it may indicate an upstream bug.
Defensive patterns

Strategy: validation

Validate before calling

// Check an action config value for ephemeral marks before marshaling.
func hasEphemeral(v cty.Value) bool {
    _, pms := v.UnmarkDeepWithPaths()
    _, _ = marks.PathsWithMark(pms, marks.Sensitive)
    ephemeral, _ := marks.PathsWithMark(pms, marks.Ephemeral) // simplified
    return len(ephemeral) > 0
}

Prevention

When it happens

Trigger: An action block references an ephemeral variable/resource output or a value derived from one; ephemeral marks propagated through expressions into the action config.

Common situations: Using ephemeral values (write-only secrets, ephemeral resources) inside an action invocation, which the current plan-renderer does not support.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/8999da81782ae895. Report an issue: GitHub.

Appendix: source

Thrown at internal/command/jsonplan/action_invocations.go:162

	case *plans.InvokeActionTrigger:
		ai.InvokeActionTrigger = &InvokeActionTrigger{}
		if at.CallingResourceAddr != nil {
			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)...)

View on GitHub (pinned to d32a084675)