From ce246936c41da1df64c12f6e012ba3bb1eaa01c4 Mon Sep 17 00:00:00 2001 From: Moustafa Baiou Date: Tue, 21 Oct 2025 16:12:35 -0400 Subject: [PATCH] Alerting: Surface remote AM silence creation errors properly When creating silences in remote Alertmanager instances, all 4xx errors were treated as 500s. This change ensures that 4xx errors are properly surfaced as bad payload errors, allowing callers to handle them appropriately. --- pkg/services/ngalert/remote/alertmanager.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pkg/services/ngalert/remote/alertmanager.go b/pkg/services/ngalert/remote/alertmanager.go index 81e3ef40181..81175e14766 100644 --- a/pkg/services/ngalert/remote/alertmanager.go +++ b/pkg/services/ngalert/remote/alertmanager.go @@ -4,6 +4,7 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "hash/fnv" "maps" @@ -13,6 +14,7 @@ import ( "strings" "time" + openapiRuntime "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" @@ -465,6 +467,18 @@ func (am *Alertmanager) CreateSilence(ctx context.Context, silence *apimodels.Po params := amsilence.NewPostSilencesParamsWithContext(ctx).WithSilence(silence) res, err := am.amClient.Silence.PostSilences(params) if err != nil { + // Translate downstream 4xx errors into a well-known bad payload error so callers can surface HTTP 400. + // The swagger client returns typed errors and/or an *openapiRuntime.APIError with a Code field. + var badReq *amsilence.PostSilencesBadRequest + if errors.As(err, &badReq) { + return "", fmt.Errorf("%w: %v", alertingNotify.ErrCreateSilenceBadPayload, err) + } + var apiErr *openapiRuntime.APIError + if errors.As(err, &apiErr) { + if apiErr.Code >= http.StatusBadRequest && apiErr.Code < http.StatusInternalServerError { + return "", fmt.Errorf("%w: %v", alertingNotify.ErrCreateSilenceBadPayload, err) + } + } return "", err }