pulumi/pulumi · error

Protocol must be configured by the time plugin configuration

Error message

Protocol must be configured by the time plugin configuration has been resolved

What it means

getPluginConfig checks that p.protocol was set (via ConfigureAgent/protocol wiring) before the plugin's configuration promise resolves. If configuration resolution completes but no gRPC protocol was ever configured, the provider plugin's internal state is inconsistent and it returns this error instead of proceeding with a nil protocol. This is an internal engine invariant, usually surfaced only in tests or when provider setup was skipped.

Source

Thrown at pkg/resource/plugin/provider_plugin.go:139

	// True if this plugin accepts strings containing bytes that are not valid UTF-8.
	acceptsByteString bool
}

// pluginConfig holds the configuration of the provider
// as specified by the Configure call.
type pluginConfig struct {
	known bool // true if all configuration values are known.
}

func (p *provider) getPluginConfig(ctx context.Context) (pluginProtocol, pluginConfig, error) {
	pcfg, err := p.configSource.Promise().Result(ctx)
	if err != nil {
		return pluginProtocol{}, pluginConfig{}, err
	}

	if p.protocol == nil {
		return pluginProtocol{}, pluginConfig{}, errors.New(
			"Protocol must be configured by the time plugin configuration has been resolved",
		)
	}

	return *p.protocol, pcfg, nil
}

// Checks PULUMI_DEBUG_PROVIDERS environment variable for any overrides for the provider identified
// by pkg. If the user has requested to attach to a live provider, returns the port number from the
// env var. For example, `PULUMI_DEBUG_PROVIDERS=aws:12345,gcp:678` will result in 12345 for aws.
func GetProviderAttachPort(pkg tokens.Package) (*int, error) {
	var optAttach string

	if providersEnvVar, has := os.LookupEnv("PULUMI_DEBUG_PROVIDERS"); has {
		for provider := range strings.SplitSeq(providersEnvVar, ",") {
			parts := strings.SplitN(provider, ":", 2)

			if parts[0] == pkg.String() {

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Ensure the provider is created through NewProvider/NewProviderWithClient so the engine wires the protocol during construction.
  2. In test harnesses, call the provider's protocol-set entry point (p.protocol) before triggering Configure/config resolution.
  3. Upgrade the Pulumi engine — if triggered from normal CLI usage this indicates an internal bug; file an issue with the stack trace.
  4. Re-run the deployment; if persistent with a specific plugin, test attaching it without PULUMI_DEBUG_PROVIDERS overrides.

Example fix

// before (custom harness)
p := &provider{configSource: src}
p.getPluginConfig(ctx) // protocol nil
// after
p, err := plugin.NewProvider(host, ctx, spec, nil, false, "")
p.Configure(ctx, req)
Defensive patterns

Strategy: validation

Validate before calling

if p.protocol == nil {
    return errors.New("protocol must be configured before resolving plugin config")
}

Prevention

When it happens

Trigger: Calling provider methods that resolve plugin config (e.g. Configure/GetPluginConfig path in provider_plugin.go) on a provider constructed without SetProtocol / without the engine having assigned a pluginProtocol; racing code paths where Configure resolves before protocol assignment in custom hosts or tests.

Common situations: Embedding the provider host in a custom engine/test harness and forgetting to set the protocol; unit tests constructing provider{} directly; engine bugs where protocol setup is skipped for dynamically attached providers.

Related errors


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