temporalio/temporal · critical

unsupported error type: %v

Error message

unsupported error type: %v

What it means

configuredFaultInjector builds fault objects from dynamic-config fault-injection rules, mapping an error type name (e.g. "ResourceExhausted", "Unavailable") to a concrete serviceerror constructor. An error name outside the supported set panics, because fault injection config is validated only at use time. This is a configuration-driven panic, so bad dynamic config can crash the calling service.

Source

Thrown at common/persistence/faultinjection/fault.go:57

		return newFaultFromError(fmt.Errorf("%s: %w", header, context.DeadlineExceeded), errRate)
	case "Timeout":
		return newFaultFromError(&persistence.TimeoutError{Msg: fmt.Sprintf("%s: persistence.TimeoutError", header)}, errRate)
	case "ExecuteAndTimeout":
		// Special error which emulates case, when caller got a Timeout error,
		// but operation actually reached persistence and was executed successfully.
		f := newFaultFromError(&persistence.TimeoutError{Msg: fmt.Sprintf("%s: persistence.TimeoutError", header)}, errRate)
		f.execOp = true
		return f
	case "ResourceExhausted":
		return newFaultFromError(&serviceerror.ResourceExhausted{
			Cause:   enumspb.RESOURCE_EXHAUSTED_CAUSE_SYSTEM_OVERLOADED,
			Scope:   enumspb.RESOURCE_EXHAUSTED_SCOPE_SYSTEM,
			Message: fmt.Sprintf("%s: serviceerror.ResourceExhausted", header),
		}, errRate)
	case "Unavailable":
		return newFaultFromError(serviceerror.NewUnavailablef("%s: serviceerror.Unavailable", header), errRate)
	default:
		panic(fmt.Sprintf("unsupported error type: %v", errName))
	}
}

func (f *fault) inject(op func() error) error {
	if f == nil {
		return op()
	}
	if f.execOp {
		err := op()
		if err != nil {
			return err
		}
	}
	return f.err
}

View on GitHub (pinned to bde624efd1)

Solutions

  1. Check the fault-injection dynamic config entry and correct the error name to a supported value (e.g. "ResourceExhausted", "Unavailable")
  2. Match the exact casing used in the switch statement in common/persistence/faultinjection/fault.go
  3. Validate fault-injection config in a staging environment before applying to production
  4. If you need another error type, add a case to newFault's switch and deploy the change

Example fix

// before (dynamic config YAML)
faultInjection:
  error: ResourceExhaustion   # typo -> panic
// after
faultInjection:
  error: ResourceExhausted    # supported name
Defensive patterns

Strategy: validation

Validate before calling

supported := map[string]bool{"ResourceExhausted": true, "Unavailable": true}
if !supported[errName] {
	return fmt.Errorf("unsupported fault injection error type: %q", errName)
}

Prevention

When it happens

Trigger: Setting the fault-injection dynamic config with an error name not in the supported map (typos like "ResourceExhaustion", unsupported types like "InvalidArgument" if unimplemented, or wrong casing) — newFault is then called with that errName.

Common situations: Typos or wrong casing in fault-injection dynamic config values; copying config examples from newer versions supporting more error types; enabling fault injection in production config by mistake.

Related errors


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/c9f0aebdcde771b3. Report an issue: GitHub.