amir20/dozzle · error

missing token parameter

Error message

missing token parameter

What it means

cloudCallback is the OAuth-style redirect handler for the Dozzle cloud (doligence) service. It reads `token` (and `from`) from the callback URL query string; if `token` is missing or empty it returns 400 with this message. The token is required to exchange for a cloud key on the remote service.

Solutions

  1. Retry the cloud connect flow from the beginning so a fresh token is included in the redirect.
  2. Check that the redirect URL reaching dozzle still contains ?token=... (inspect reverse proxy / cloud redirect config).
  3. If a proxy strips query params, fix the proxy configuration to preserve the full request URI.

Example fix

// before
https://dozzle.example.com/cloud/callback
// after
https://dozzle.example.com/cloud/callback?token=<jwt>&from=agents
Defensive patterns

Strategy: validation

Validate before calling

const url = new URL(window.location.href);
if (!url.searchParams.get('token')) {
    // restart the cloud connect flow instead of using this callback URL
}

Type guard

function hasToken(params: URLSearchParams): params is URLSearchParams & { get(k: 'token'): string } {
    return !!params.get('token');
}

Prevention

When it happens

Trigger: Visiting /cloud/callback (or equivalent route) without a `token` query parameter, e.g. navigating directly to the callback URL, a truncated redirect URL, or a misconfigured cloud-side redirect that drops the query string.

Common situations: User bookmarks or shares the callback URL without params; reverse proxy strips query strings; the cloud service redirects incorrectly after login failure; copying the URL partially from the browser.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07). Data as JSON: /api/errors/3b4a0031b890f7ac. Report an issue: GitHub.

Appendix: source

Thrown at internal/web/cloud.go:48

func (h *handler) requireCloudRole(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if h.config.Authorization.Provider != NONE {
			user := auth.UserFromContext(r.Context())
			if user == nil || !user.Roles.Has(auth.Cloud) {
				log.Warn().Msg("user is not permitted to manage cloud")
				http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
				return
			}
		}
		next.ServeHTTP(w, r)
	})
}

func (h *handler) cloudCallback(w http.ResponseWriter, r *http.Request) {
	token := r.URL.Query().Get("token")
	from := r.URL.Query().Get("from")
	if token == "" {
		http.Error(w, "missing token parameter", http.StatusBadRequest)
		return
	}

	cloudURL := os.Getenv("DOLIGENCE_URL")
	if cloudURL == "" {
		cloudURL = "https://doligence.dozzle.dev"
	}

	exchangeURL := fmt.Sprintf("%s/api/exchange-token", cloudURL)

	client := cloudHTTPClient
	req, err := http.NewRequestWithContext(r.Context(), http.MethodPost, exchangeURL, nil)
	if err != nil {
		log.Error().Err(err).Msg("Failed to create request")
		http.Error(w, "failed to create request", http.StatusInternalServerError)
		return
	}
	req.Header.Set("User-Agent", dispatcher.UserAgent)

View on GitHub (pinned to d9463cbe21)