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
- Reduce webhook payload size on the sender side (configure the Git host to send minimal event payloads)
- Ensure the webhook URL is only receiving intended provider events (limit event types)
- If legitimately larger payloads are needed, this is a hard-coded limit — file an issue / adjust the constant and rebuild
- 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
- Limit event types subscribed on the Git provider webhook
- Keep push payloads small (shallow diffs); avoid attaching artifacts
- Reject oversized bodies early at the ingress with 413
- Educate users that 2MB is a hard anti-DoS cap
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
- failed to get webhook clients: %w
- failed to read webhook request body: %w
- failed to unmarshal webhook client "%s": %w
- failed to get service account "%s": %w
- failed to get token secret "%s": %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/3d4e4acc325ab170.
Report an issue: GitHub.