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

  1. Inspect the '(read ...)' payload — it shows exactly what the plugin emitted instead of a clean port.
  2. Retry without debugger attachment to confirm the error is debugger-related.
  3. Check the plugin's stderr for the real crash output.
  4. Ensure plugin code doesn't print logs to stdout (must go to stderr); fix logging in the plugin if you own it.
  5. 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

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


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