juicedata/juicefs · warning

http status: %s

Error message

http status: %s

What it means

JuiceFS cluster sync supports a global traffic-control (rate limit) service addressed by a URL. globalLimit.request POSTs byte-budget requests to it; if the HTTP response status is not 200 (and no transport error occurred), it throws 'http status: <text>'. The limiter is then marked unhealthy and sync falls back to local bwlimit or unlimited.

Source

Thrown at pkg/sync/sync.go:139

			} else {
				logger.Warnf("traffic control %s is unavailable, run without rate limit", l.address)
			}
		}
	}()
	r := req{Bytes: ask}
	data, err := json.Marshal(r)
	if err != nil {
		return 0, 0, err
	}
	result, err := http.Post(l.address, "application/json", bytes.NewReader(data))
	if err != nil || result.StatusCode != http.StatusOK {
		var status string
		if result != nil {
			status = http.StatusText(result.StatusCode)
		}
		logger.Warnf("request traffic control %s failed: %s, http status: %s", l.address, err, status)
		if err == nil {
			err = fmt.Errorf("http status: %s", status)
		}
		return 0, 0, err
	}
	defer result.Body.Close()
	content, err := io.ReadAll(result.Body)
	if err != nil {
		return 0, 0, err
	}
	res := resp{}
	if err = json.Unmarshal(content, &res); err != nil {
		return 0, 0, err
	}
	return res.Granted, res.Expired, nil
}

func (l *globalLimit) wait(bytes int64) bool {
	l.Lock()
	defer l.Unlock()

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Check the wrapped log line 'request traffic control <addr> failed: <err>, http status: <text>' to see the exact status and fix the limiter service or its URL
  2. Verify the --limit-manager address points at the correct host/port/path of the traffic-control service
  3. Confirm the limiter service is running and healthy (curl -X POST the endpoint with {"bytes":1024})
  4. If the fallback is acceptable, this is non-fatal: sync continues with local bwlimit or no limit

Example fix

// before
juicefs sync a b --cluster w1 --limit-manager http://10.0.0.1:8000/wrong
// -> http status: Not Found
// after
juicefs sync a b --cluster w1 --limit-manager http://10.0.0.1:8000
Defensive patterns

Strategy: try-catch

Validate before calling

resp, err := http.Post(limitManagerURL, "application/json", bytes.NewReader([]byte(`{"bytes":1024}`)))
if err != nil || (resp != nil && resp.StatusCode != http.StatusOK) {
	status := ""
	if resp != nil {
		status = http.StatusText(resp.StatusCode)
	}
	log.Printf("traffic control %s unhealthy (status %s); local bwlimit fallback will be used", limitManagerURL, status)
}

Try / catch

granted, expired, err := limiter.request(ask)
if err != nil {
	var statusErr = fmt.Errorf("http status: %s", status)
	if errors.Is(err, statusErr) {
		logger.Warnf("limiter %s returned non-200; continuing with local bwlimit fallback", l.address)
		return fallbackLocalLimit(ask)
	}
	return 0, 0, err
}

Prevention

When it happens

Trigger: The traffic-control endpoint responds with a non-200 status (404 wrong path, 403 auth, 500 crash, 502 proxy error) to the POST of {"bytes": N}.

Common situations: Misconfigured --limit-manager URL (wrong port/path); rate-limit service not running or behind a proxy returning 502/503; service rejecting unauthenticated requests.

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 juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/612c3c4de6c7a31e. Report an issue: GitHub.