cloudflare/cloudflared · error
ErrUnauthorized
ErrUnauthorized
Error message
unauthorized
What it means
ErrUnauthorized is a sentinel error in cloudflared's cfapi REST client returned by statusCodeToError when the Cloudflare API responds with HTTP 401 (Unauthorized) or 403 (Forbidden). It means the request was rejected by authentication/authorization before any resource-level work happened.
Source
Thrown at cfapi/base_client.go:24
"fmt"
"io"
"net/http"
"net/url"
"strings"
"time"
"github.com/pkg/errors"
"github.com/rs/zerolog"
"golang.org/x/net/http2"
)
const (
defaultTimeout = 15 * time.Second
jsonContentType = "application/json"
)
var (
ErrUnauthorized = errors.New("unauthorized")
ErrBadRequest = errors.New("incorrect request parameters")
ErrNotFound = errors.New("not found")
ErrAPINoSuccess = errors.New("API call failed")
)
type RESTClient struct {
baseEndpoints *baseEndpoints
authToken string
userAgent string
client http.Client
log *zerolog.Logger
}
type baseEndpoints struct {
accountLevel url.URL
zoneLevel url.URL
accountRoutes url.URL
accountVnets url.URLView on GitHub (pinned to 2253eeeb25)
Solutions
- Regenerate the API/service token and update the configuration (TUNNEL_TOKEN or credentials file).
- Verify the token's policy includes the needed permissions (e.g. Account: Cloudflare Tunnel:Edit).
- Check account/zone IDs in the request match the token's account scope.
- Retry after confirming clock sync (NTP) if using time-bound tokens.
Example fix
// before
client, err := cfapi.NewRESTClient(..., "stale-token", ...)
// after
client, err := cfapi.NewRESTClient(..., os.Getenv("TUNNEL_API_TOKEN"), ...) // token freshly rotated and scoped Defensive patterns
Strategy: try-catch
Validate before calling
if os.Getenv("TUNNEL_API_TOKEN") == "" {
return errors.New("TUNNEL_API_TOKEN must be set before calling the cfapi client")
} Type guard
import "errors"
func IsUnauthorized(err error) bool {
return errors.Is(err, ErrUnauthorized)
} Try / catch
resp, err := client.GetTunnel(ctx, accountID, tunnelID)
if err != nil {
if errors.Is(err, ErrUnauthorized) {
// refresh token / re-authenticate before retrying
return fmt.Errorf("check API token and scopes: %w", err)
}
return err
} Prevention
- Rotate tokens on a schedule and update the daemon's credentials
- Scope the token policy to Cloudflare Tunnel Edit for the right account
- Keep server clocks NTP-synced to avoid token validation failures
When it happens
Trigger: Any cfapi REST call (tunnel, VM, config endpoints) where the API token/service token is missing, expired, revoked, or lacks scopes for the endpoint; cloudflared receiving 401/403 from api.cloudflare.com during tunnel management operations.
Common situations: Expired or rotated API tokens left in config, tunnel tokens copied incorrectly, an account whose token lacks the Cloudflare Tunnel edit permission, clock skew invalidating tokens, or hitting an endpoint the token's policy does not cover.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- ErrBadRequest
- Create Tunnel API call failed
- failed to get checksums: {0}
- failed to upload checksum: {0}
- ErrAPINoSuccess
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/8a9b19ca17320933.
Report an issue: GitHub.