argoproj/argo-workflows · warning

webhook request body exceeds maximum size of 2MB

Error message

webhook request body exceeds maximum size of 2MB

What it means

To prevent denial-of-service, the interceptor caps webhook bodies at 2MB. If the buffered body exceeds maxWebhookSize the request is rejected outright with this static error — no signature verification is attempted.

Source

Thrown at server/auth/webhook/interceptor.go:86

	}
	namespace := parts[0]
	secretsInterface := kube.CoreV1().Secrets(namespace)
	ctx := r.Context()

	webhookClients, err := secretsInterface.Get(ctx, "argo-workflows-webhook-clients", metav1.GetOptions{})
	if err != nil {
		return fmt.Errorf("failed to get webhook clients: %w", err)
	}
	// we need to read the request body to check the signature, but we still need it for the GRPC request,
	// so read it all now, and then reinstate when we are done.
	// Limit to 2MB to prevent denial-of-service via oversized webhook payloads.
	const maxWebhookSize = 2 * 1024 * 1024 // 2MB
	buf, err2 := io.ReadAll(io.LimitReader(r.Body, maxWebhookSize+1))
	if err2 != nil {
		return fmt.Errorf("failed to read webhook request body: %w", err2)
	}
	if len(buf) > maxWebhookSize {
		return fmt.Errorf("webhook request body exceeds maximum size of 2MB")
	}
	defer func() { r.Body = io.NopCloser(bytes.NewBuffer(buf)) }()
	serviceAccountInterface := kube.CoreV1().ServiceAccounts(namespace)
	for serviceAccountName, data := range webhookClients.Data {
		r.Body = io.NopCloser(bytes.NewBuffer(buf))
		client := &webhookClient{}
		err := yaml.Unmarshal(data, client)
		if err != nil {
			return fmt.Errorf("failed to unmarshal webhook client \"%s\": %w", serviceAccountName, err)
		}
		i.logger.WithFields(logging.Fields{"serviceAccountName": serviceAccountName, "webhookType": client.Type}).Debug(r.Context(), "Attempting to match webhook request")
		ok := webhookParsers[client.Type](client.Secret, r)
		if ok {
			i.logger.WithField("serviceAccountName", serviceAccountName).Debug(r.Context(), "Matched webhook request")
			serviceAccount, err := serviceAccountInterface.Get(ctx, serviceAccountName, metav1.GetOptions{})
			if err != nil {
				return fmt.Errorf("failed to get service account \"%s\": %w", serviceAccountName, err)
			}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Reduce webhook payload size on the sender side (configure the Git host to send minimal event payloads)
  2. Ensure the webhook URL is only receiving intended provider events (limit event types)
  3. If legitimately larger payloads are needed, this is a hard-coded limit — file an issue / adjust the constant and rebuild
  4. Confirm no client is accidentally posting large files to the webhook route
Defensive patterns

Strategy: validation

Validate before calling

if r.ContentLength > 2*1024*1024 {
    http.Error(w, "webhook request body exceeds maximum size of 2MB", http.StatusRequestEntityTooLarge)
    return
}

Prevention

When it happens

Trigger: A POST to a webhook endpoint whose payload (e.g. a GitHub push event with a huge diff/payload or misconfigured sender) exceeds 2*1024*1024 bytes, so io.LimitReader(…, max+1) reads more than 2MB.

Common situations: Git providers sending very large push events; misconfigured webhooks sending full artifact contents; a client using the webhook route for non-webhook data uploads.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/3d4e4acc325ab170. Report an issue: GitHub.