pulumi/pulumi · error
failure reading plugin [%v] (read '%v'): %s
Error message
failure reading plugin [%v] (read '%v'): %s
What it means
Same handshake-failure path as 'could not read plugin', but this variant fires when a debug/attach port string was captured (portString non-empty, i.e. a debugger was attached or port info existed). It reports what was read from the plugin along with the read error, to aid debugging an attached plugin session.
Source
Thrown at sdk/go/common/resource/plugin/plugin.go:416
// If theres no error from waiting then just report the EOF
if readerr == nil {
readerr = io.EOF
}
}
var errMsg string
detailed, ok := rpcerror.FromError(readerr)
if ok {
errMsg = detailed.Error()
} else {
errMsg = readerr.Error()
}
// Fall back to a generic, opaque error.
if portString == "" {
return nil, nil, fmt.Errorf("could not read plugin [%v]: %s", bin, errMsg)
}
return nil, nil, fmt.Errorf("failure reading plugin [%v] (read '%v'): %s",
bin, portString, errMsg)
}
if n > 0 && b[0] == '\n' {
break
}
portString += string(b[:n])
}
// Parse the output line to ensure it's a numeric port.
var port int
if port, err = parsePort(portString); err != nil {
killerr := plug.Kill()
contract.IgnoreError(killerr) // ignoring the error because the existing one trumps it.
return nil, nil, fmt.Errorf(
"%v plugin [%v] wrote an invalid port to stdout: %w", prefix, bin, err)
}
// After reading the port number, set up a tracer on stdout just so other output doesn't disappear.
stdoutDone := make(chan bool)View on GitHub (pinned to 793f7b2e16)
Solutions
- Inspect the '(read ...)' payload — it shows exactly what the plugin emitted instead of a clean port.
- Retry without debugger attachment to confirm the error is debugger-related.
- Check the plugin's stderr for the real crash output.
- Ensure plugin code doesn't print logs to stdout (must go to stderr); fix logging in the plugin if you own it.
- Reinstall or rebuild the plugin binary.
Example fix
// before: plugin's fmt.Println('starting...') corrupts handshake
fmt.Println("starting provider...")
// after
fmt.Fprintf(os.Stderr, "starting provider...\n") Defensive patterns
Strategy: fallback
Validate before calling
// reproduce without debugger attachment first unset PULUMI_DEBUG_PLUGINS; pulumi up
Try / catch
catch (err) {
if (/failure reading plugin/.test(err.message)) {
// inspect the quoted '(read ...)' payload for what the plugin emitted
}
} Prevention
- Disable plugin debugger attachment in normal CI runs.
- In plugin code, never use fmt.Print* to stdout for logging.
- Check for security agents/wrappers intercepting subprocess stdout.
- Rebuild plugins with a current Pulumi SDK.
When it happens
Trigger: Run's stdout read fails while an attach/debugger port was configured (attachDebugger path), so the error includes the literal string read from the plugin's stdout.
Common situations: Developer attached a debugger to a provider (PULUMI_DEBUG_PLUGINS or --attach-debugger) and the plugin died mid-handshake; garbled output on stdout from debug logging contaminating the port line.
Related errors
- could not read plugin [%v]: %s
- %v plugin [%v] wrote an invalid port to stdout: %w
- failed to handshake with '%v': %w
- failed to handshake with '%v': %w
- failed to validate provider config: %w
AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31).
Data as JSON: /api/errors/19417e77e617a9e5.
Report an issue: GitHub.