GoogleContainerTools/skaffold · error

PORT_FORWARD_RUN_PROXY_START_ERROR

PORT_FORWARD_RUN_PROXY_START_ERROR

Error message

unable to start port forward: %w

What it means

In `runProxyForwarder.Start`, skaffold spawns a background `gcloud ... proxy` process (via `exec.CommandContext(...).Start()`) for each Cloud Run resource being port-forwarded. If the process fails to *start* (as opposed to exiting later), the error is wrapped as 'unable to start port forward: %w' with code PORT_FORWARD_RUN_PROXY_START_ERROR and the port-forward task is marked failed.

Source

Thrown at pkg/skaffold/deploy/cloudrun/accessor.go:168

		return nil
	}
	for _, resource := range r.resources.resources {
		if resource.port == 0 {
			port := retrieveAvailablePort("localhost", 8080, r.resources.forwardedPorts)
			resource.port = port
		}
		if !resource.started {
			eventV2.TaskInProgress(constants.PortForward, "port forward URLs")
			// has not been started yet
			cctx, cancel := context.WithCancel(ctx)
			output.Yellow.Fprintf(out, "Forwarding service %s to local port %d\n", resource.name.String(), resource.port)
			cmd := exec.CommandContext(cctx, "gcloud", getGcloudProxyArgs(resource.name, resource.port)...)
			cmd.Stdout = out
			cmd.Stderr = out
			resource.cancel = cancel
			if err := cmd.Start(); err != nil {
				eventV2.TaskFailed(constants.PortForward, err)
				return sErrors.NewError(fmt.Errorf("unable to start port forward: %w", err), &proto.ActionableErr{ErrCode: proto.StatusCode_PORT_FORWARD_RUN_PROXY_START_ERROR})
			}
			go func() {
				err := cmd.Wait()
				if err != nil {
					eventV2.TaskFailed(constants.PortForward, err)
				} else {
					eventV2.TaskSucceeded(constants.PortForward)
				}
			}()
			eventV2.PortForwarded(int32(resource.port), schemautil.FromInt(443), "", "", resource.name.Project, "", "run-service", resource.name.Service, resource.name.String())
			resource.started = true
			resource.cmd = cmd
		}
	}
	return nil
}

func getGcloudProxyArgs(resource RunResourceName, port int) []string {

View on GitHub (pinned to a1189de023)

Solutions

  1. Read the wrapped cause (`%w`) at the end of the message to identify the underlying exec failure and fix it
  2. Re-run after cancelling: transient context-cancellation during startup is expected; restart `skaffold dev`
  3. Check available resources (PID/memory limits) if the cause is 'fork/exec: cannot allocate memory' or similar
  4. Reinstall/repair the gcloud SDK if the cause indicates a missing or damaged binary
  5. Verify the resource name and port used for the proxy (from the skaffold Cloud Run config) are valid
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the proxy command can at least be resolved and args look sane before spawning
if _, err := exec.LookPath("gcloud"); err != nil {
	return fmt.Errorf("gcloud unavailable, cannot start Cloud Run proxy: %w", err)
}

Try / catch

if err := forwarder.Start(ctx, out); err != nil {
	var sErr *sErrors.Error
	if errors.As(err, &sErr) && sErr.Status().ErrCode == proto.StatusCode_PORT_FORWARD_RUN_PROXY_START_ERROR {
		log.Warnf("Cloud Run proxy failed to start: %v — retrying once", err)
		time.Sleep(2 * time.Second)
		return forwarder.Start(ctx, out)
	}
	return err
}

Prevention

When it happens

Trigger: `cmd.Start()` fails while iterating over `r.resources.resources` — e.g. the exec context was already cancelled (`cctx` cancelled), the gcloud binary disappeared between the install check and the exec, OS resource limits (fork/exec failures), or invalid arguments built by `getGcloudProxyArgs`.

Common situations: User hits Ctrl-C / the context is cancelled while forwards are being set up; out-of-memory or PID exhaustion in constrained CI containers; a corrupted or partially-installed gcloud SDK; port numbers that cause gcloud to reject args immediately.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/d7502329fda8ae78. Report an issue: GitHub.