SigNoz/signoz · error · errors.Error
ErrCodeInvalidState
ErrCodeInvalidState
Error message
saml: invalid state
What it means
Default branch of the filter-operator switch in PrepareTimeseriesFilterQuery (SigNoz metrics v4 helpers, sub_query.go). Each tag filter item carries a FilterOperator (=, !=, in, like, ilike, exists, etc.); when an item's operator has no case here the builder cannot emit a ClickHouse WHERE condition and fails.
Source
Thrown at ee/authn/callbackauthn/samlcallbackauthn/authn.go:59
func (a *AuthN) LoginURL(ctx context.Context, siteURL *url.URL, authDomain *authtypes.AuthDomain) (string, error) {
sp, err := a.serviceProvider(siteURL, authDomain)
if err != nil {
return "", err
}
url, err := sp.BuildAuthURL(authtypes.NewState(siteURL, authDomain.StorableAuthDomain().ID).URL.String())
if err != nil {
return "", err
}
return url, nil
}
func (a *AuthN) HandleCallback(ctx context.Context, formValues url.Values) (*authtypes.CallbackIdentity, error) {
state, err := authtypes.NewStateFromString(formValues.Get("RelayState"))
if err != nil {
return nil, errors.New(errors.TypeInvalidInput, authtypes.ErrCodeInvalidState, "saml: invalid state").WithAdditional(err.Error())
}
authDomain, err := a.store.GetAuthDomainFromID(ctx, state.DomainID)
if err != nil {
return nil, err
}
_, err = a.licensing.GetActive(ctx, authDomain.StorableAuthDomain().OrgID)
if err != nil {
return nil, errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
}
samlConfig, err := authDomain.Config().SamlConfig()
if err != nil {
return nil, err
}
sp, err := a.serviceProvider(state.URL, authDomain)View on GitHub (pinned to 5069bf80b0)
Solutions
- Log the failing filter item and replace its operator with one supported by the v4 sub-query builder (=, !=, in, nin, contains/matches-style like operators, exists, nexists, ilike variants)
- Keep SigNoz UI and query-service versions in sync so v4 filter operators line up
- Add a pre-validation pass over qp.Filters rejecting unknown operators before building
Example fix
// before
filters: []v3.FilterItem{{Key: tagKey, Operator: ">", Value: "abc"}}
// after
filters: []v3.FilterItem{{Key: tagKey, Operator: v3.FilterOperatorEqual, Value: "abc"}} Defensive patterns
Strategy: validation
Validate before calling
var v4FilterOps = map[v3.FilterOperator]bool{v3.FilterOperatorEqual: true, v3.FilterOperatorNotEqual: true, v3.FilterOperatorIn: true, v3.FilterOperatorNotIn: true, v3.FilterOperatorLike: true, v3.FilterOperatorILike: true, v3.FilterOperatorNotILike: true, v3.FilterOperatorExists: true, v3.FilterOperatorNotExists: true}
for _, f := range qp.Filters {
if !v4FilterOps[f.Operator] {
return fmt.Errorf("filter operator %q not supported", f.Operator)
}
} Type guard
null
Try / catch
if _, err := helpers.PrepareTimeseriesFilterQuery(...); err != nil && strings.Contains(err.Error(), "unsupported filter operator") {
// strip or rewrite the offending filter and rebuild
} Prevention
- Mirror the builder's operator switch as a shared allowlist
- Test dashboards against the v4 path before release
- Reject unknown operators at API ingress with field-level errors
When it happens
Trigger: A v4 metrics query whose filters array contains an item with an operator outside the handled set — e.g. '>' with string operands, an operator string typo, or an operator supported only in the v3 builder. Reached via prepareTimeAggregationSubQuery / prepareQueryOptimized.
Common situations: Migrating dashboards from v3 to v4 query APIs where the operator vocabularies differ; UI sending an operator the backend v4 path hasn't implemented yet; programmatic filter construction reusing enums from another package.
Related errors
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/e7c2acee9b095ab0.
Report an issue: GitHub.