cloudflare/cloudflared · error

Expected to find a single tunnel with uuid %v but found %d t

Error message

Expected to find a single tunnel with uuid %v but found %d tunnels.

What it means

getTunnel queries the Cloudflare API filtered by tunnel UUID and asserts exactly one result. When the API returns zero matches (never existed / deleted / different account) or more than one (unexpected server-side state), it errors with 'Expected to find a single tunnel with uuid %v but found %d tunnels.'

Source

Thrown at cmd/cloudflared/tunnel/subcommands.go:611

	if len(clients) > 0 {
		formatAndPrintConnectionsList(info, c.Bool("show-recently-disconnected"))
	} else {
		fmt.Printf("Your tunnel %s does not have any active connection.\n", tunnelID)
	}

	return nil
}

func getTunnel(sc *subcommandContext, tunnelID uuid.UUID) (*cfapi.Tunnel, error) {
	filter := cfapi.NewTunnelFilter()
	filter.ByTunnelID(tunnelID)
	tunnels, err := sc.list(filter)
	if err != nil {
		return nil, err
	}
	if len(tunnels) != 1 {
		return nil, errors.Errorf("Expected to find a single tunnel with uuid %v but found %d tunnels.", tunnelID, len(tunnels))
	}
	return tunnels[0], nil
}

func formatAndPrintConnectionsList(tunnelInfo Info, showRecentlyDisconnected bool) {
	writer := tabWriter()
	defer func() { _ = writer.Flush() }()

	// Print the general tunnel info table
	_, _ = fmt.Fprintf(writer, "NAME:     %s\nID:       %s\nCREATED:  %s\n\n", tunnelInfo.Name, tunnelInfo.ID, tunnelInfo.CreatedAt)

	// Determine whether to print the connector table
	shouldDisplayTable := false
	for _, c := range tunnelInfo.Connectors {
		conns := fmtConnections(c.Connections, showRecentlyDisconnected)
		if len(conns) > 0 {
			shouldDisplayTable = true
		}

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Verify the UUID belongs to the logged-in account: `cloudflared tunnel list` and cross-check
  2. Run `cloudflared tunnel login` to ensure the cert.pem matches the intended account
  3. If found 0: the tunnel was deleted or never existed — create a new one or fix the ID
  4. If found >1: retry; if persistent, report to Cloudflare since duplicate UUIDs are unexpected

Example fix

// before
cloudflared tunnel info 11111111-1111-1111-1111-111111111111   # other account
// after
cloudflared tunnel login   # switch to correct account
cloudflared tunnel info 11111111-1111-1111-1111-111111111111
Defensive patterns

Strategy: retry

Validate before calling

out, _ := exec.Command("cloudflared", "tunnel", "list", "--output", "json").Output()
var tunnels []map[string]any
json.Unmarshal(out, &tunnels)
found := 0
for _, t := range tunnels { if t["id"] == wantID { found++ } }
if found != 1 { return fmt.Errorf("uuid %s matches %d tunnels in this account", wantID, found) }

Try / catch

tunnels, err := sc.list(filter)
if err != nil { return nil, err }
if len(tunnels) != 1 {
	// retry once for transient API inconsistency, else surface
	return nil, fmt.Errorf("expected 1 tunnel for uuid %v, found %d", tunnelID, len(tunnels))
}

Prevention

When it happens

Trigger: Calling `cloudflared tunnel info <uuid>` (or delete by ID) with a UUID that does not exist in the currently authenticated account, or an API response returning duplicate/empty rows for the ByTunnelID filter.

Common situations: Querying a tunnel from the wrong Cloudflare account (stale cert.pem for another account); tunnel already deleted; copy-pasting a UUID across accounts or environments (staging vs prod); API inconsistency returning duplicates.

Related errors


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/9d3c21265e904536. Report an issue: GitHub.