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
- Verify the UUID belongs to the logged-in account: `cloudflared tunnel list` and cross-check
- Run `cloudflared tunnel login` to ensure the cert.pem matches the intended account
- If found 0: the tunnel was deleted or never existed — create a new one or fix the ID
- 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
- Confirm account identity (cert.pem) matches the tunnel's account before info/delete
- Keep a registry mapping tunnel IDs to accounts/environments
- Re-login after switching Cloudflare accounts
- Treat duplicate UUID results as an API bug and report with request IDs
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
- failed to create tunnel
- ErrTunnelNameConflict
- v.Error
- error parsing tunnel ID
- failed to get checksums: {0}
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/9d3c21265e904536.
Report an issue: GitHub.