Pulumi Error: 'Diff Failed' Provider Panic During Preview or Up
Fix Pulumi 'Diff failed' and provider 'panic: runtime error' crashes during preview/up: diagnose plugin crashes, version mismatches, and malformed inputs.
- #pulumi
- #iac
- #troubleshooting
- #errors
Stuck on this Pulumi error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Exact Error Message
error: Preview failed: Diff failed: rpc error: code = Unavailable desc = transport is closing
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x1a3c9f1]
goroutine 42 [running]:
github.com/pulumi/pulumi-aws/provider/pkg/...
error: an unhandled error occurred: rpc error: code = Unavailable desc = error reading from server: EOF
The two tell-tale signs are a Diff failed (or Check failed / Create failed) RPC error paired with a Go panic: stack trace and SIGSEGV. The transport is closing / EOF follows because the provider plugin process crashed and its gRPC connection died mid-operation.
What It Means
Pulumi runs each provider (AWS, GCP, Kubernetes, etc.) as a separate plugin process and talks to it over gRPC. During pulumi preview or pulumi up, the engine calls the provider’s Diff method to compute what changed. A panic means that provider process crashed instead of returning an answer. Because the plugin died, the engine loses the connection and reports the RPC as Unavailable/EOF.
This is a bug or an unhandled edge case inside the provider plugin, not a mistake in the Pulumi engine. It is frequently triggered by a specific input shape (a nil field the provider does not guard against) or by a mismatch between the provider version and the SDK version your program was compiled with.
Common Causes
- A genuine bug in the provider plugin that panics on a particular input (often a nil or unexpected type in one resource’s args).
- The installed provider plugin version does not match the language SDK version imported in your program.
- A corrupt or partially-downloaded plugin binary in the plugin cache.
- An out-of-memory or resource-starved CI runner killing the plugin process (which surfaces as
EOF). - A malformed input value (e.g. an unresolved
Outputpassed where the provider expects a concrete scalar).
Diagnostic Commands
Capture the full panic and gRPC traffic:
pulumi preview --logtostderr --logflow -v=9 2>pulumi-debug.log
Check the installed plugin versions against what your program requires:
pulumi plugin ls
Isolate the crash to a single resource by previewing just one URN:
pulumi preview --target 'urn:pulumi:prod::app::aws:lb/listener:Listener::web'
Inspect the recorded inputs for the suspect resource:
pulumi stack export --show-secrets | grep -A20 'lb/listener:Listener'
Step-by-Step Resolution
-
Read the panic stack trace to identify the provider (e.g.
pulumi-aws) and, if shown, the resource type at the top of the crash. -
Narrow the blast radius with
--targetto find the single resource whose diff panics. Once you know it, you know which input to fix or which provider bug you have hit. -
Align plugin and SDK versions. Upgrade the language SDK in your program and the matching plugin together:
npm install @pulumi/aws@latest # or the version that matches your code
pulumi plugin install resource aws # engine also auto-installs on next run
- If the plugin binary may be corrupt, remove it and let Pulumi re-download a clean copy:
pulumi plugin rm resource aws --all --yes
pulumi preview
- If a specific input triggers the panic, guard it. Do not pass an unresolved or nil value where the provider expects a concrete one:
const port = args.port ?? 443; // avoid passing undefined into the provider
- Re-run and confirm the diff completes instead of crashing:
pulumi preview --diff
Resources:
~ 1 to update
2 unchanged
- If it is a confirmed provider bug on the latest version, pin to the last known-good plugin version and file an issue with the panic trace attached.
Prevention
- Keep each provider’s language SDK and plugin version in lockstep; upgrade them in the same change, not independently.
- Pin provider versions explicitly (in
package.json,go.mod, orPulumi.yamlruntime options) so plugin drift cannot happen silently. - Give CI runners enough memory; a killed plugin process looks identical to a panic (
EOF). - Validate and default resource args in your program so nil/undefined never reaches a provider call.
- Reproduce with
--targetbefore upgrading blindly, so you know whether the fix is your input or the provider version. - Use tested provider snippets from the Pulumi prompt library to avoid input shapes that commonly trip provider bugs.
Related Errors
resource registration ... timed out— a hang rather than a crash; the plugin is alive but stuck.unknown provider type/no resource plugin found— the plugin is missing, not crashing.provider version mismatch— surfaces as version conflicts, sometimes the root cause of a panic.rpc error: code = Unavailable desc = transport is closing— the connection-level symptom that accompanies any plugin crash.
Frequently Asked Questions
Is a provider panic my code’s fault or the provider’s? It is a provider bug that your input exposed. A well-behaved provider should return an error, not crash, so the ideal fix is upgrading the provider; the practical fix is often avoiding the input that triggers it.
Why do I see EOF and transport is closing alongside the panic? Those are the gRPC layer noticing the plugin process died. They are symptoms of the crash, not separate problems.
Could this just be low memory in CI? Yes. An OOM-killed plugin looks like a crash. If the panic trace is absent and you only see EOF, check the runner’s memory before assuming a provider bug.
How do I confirm a version mismatch is the cause? Run pulumi plugin ls and compare against the SDK version in your dependency manifest. Bumping both to the same release resolves a large share of these crashes.
What if only the latest provider version panics? Pin to the previous working version with an explicit constraint, re-run, and open an upstream issue with the full panic trace. For more provider and plugin patterns, see the Pulumi guides.
Fixed it? Get 500 Pulumi & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.