chenhg5/cc-connect · critical

cloud_web: register HTTP %d: %s

Error message

cloud_web: register HTTP %d: %s

What it means

The long-poll transport's register call reached the cloud-web server but got a response with a status code other than HTTP 200. The status and the first up-to-1MB of the response body are included so the cause (auth rejection, bad path, server error) is visible. This aborts Platform.Start for poll mode.

Source

Thrown at platform/cloud-web/poll.go:114

	}
	url := joinURL(t.baseURL, defaultRegister)
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", "application/json")
	authHTTP(req, t.token)
	resp, err := t.client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("cloud_web: register request: %w", err)
	}
	defer func() { _ = resp.Body.Close() }()
	raw, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20))
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("cloud_web: register HTTP %d: %s", resp.StatusCode, string(raw))
	}
	return parseRegisterAck(raw)
}

func (t *pollTransport) pollLoop(ctx context.Context) {
	for {
		select {
		case <-ctx.Done():
			return
		default:
		}
		if err := t.pollOnce(ctx); err != nil {
			if ctx.Err() != nil {
				return
			}
			slog.Debug("cloud_web: long poll error", "error", err)
			time.Sleep(time.Second)
		}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Decode the error: 401 -> correct the token in config; 404/405 -> fix base_url/register path; 5xx -> inspect cloud-web server logs.
  2. Verify the token exactly matches the server's configured secret.
  3. curl -X POST -H 'Authorization: Bearer <token>' -H 'Content-Type: application/json' -d '{}' {base_url}/register to reproduce outside cc-connect.
  4. Upgrade/align server and client versions if the register endpoint is missing.

Example fix

// config.toml — before
token = "stale-token"  # server rotated -> 401

// after
token = "<current-shared-secret>"
Defensive patterns

Strategy: try-catch

Validate before calling

// reproduce register outside the app before startup
body := strings.NewReader(fmt.Sprintf(`{"register":{"name":"%s","project":"%s"}}`, name, project))
req, _ := http.NewRequest("POST", baseURL+"/register", body)
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err == nil {
    defer resp.Body.Close()
    if resp.StatusCode != 200 {
        return fmt.Errorf("register endpoint returned %d; check token/path", resp.StatusCode)
    }
}

Try / catch

if err := platform.Start(ctx, handler); err != nil {
    if strings.Contains(err.Error(), "register HTTP 401") {
        slog.Error("cloud-web rejected the token; update token in config.toml")
    } else if strings.Contains(err.Error(), "register HTTP 404") {
        slog.Error("register path wrong; fix base_url in config.toml")
    }
    return err
}

Prevention

When it happens

Trigger: POST to {base_url}/register returns 401 (token rejected), 404 (wrong register path/base_url), 405 (method mismatch on a proxy), or 5xx (server fault).

Common situations: Token mismatch after rotating the shared secret; base_url missing an API path prefix so /register 404s; an intermediary (nginx/CDN) intercepting with 403/502; older server version that doesn't implement the register endpoint.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/3c1aca7dbd0597ce. Report an issue: GitHub.