SigNoz/signoz · error · errors.Error

CodeForbidden

CodeForbidden

Error message

saml: expired saml response

What it means

parseMetricsTime in SigNoz's parser.go accepts epoch nanoseconds (float seconds), epoch seconds, or an RFC3339(9) string; if none parse, it returns 'cannot parse %q to a valid timestamp'. It is the parameter parser for the time= field of instant and query_range metrics API requests.

Source

Thrown at ee/authn/callbackauthn/samlcallbackauthn/authn.go:96

	if err != nil {
		return nil, err
	}

	assertionInfo, err := sp.RetrieveAssertionInfo(formValues.Get("SAMLResponse"))
	if err != nil {
		if errors.As(err, &saml2.ErrVerification{}) {
			return nil, errors.New(errors.TypeForbidden, errors.CodeForbidden, err.Error())
		}

		if errors.As(err, &saml2.ErrMissingElement{}) {
			return nil, errors.New(errors.TypeNotFound, errors.CodeNotFound, err.Error())
		}

		return nil, err
	}

	if assertionInfo.WarningInfo.InvalidTime {
		return nil, errors.New(errors.TypeForbidden, errors.CodeForbidden, "saml: expired saml response")
	}

	email, err := valuer.NewEmail(assertionInfo.NameID)
	if err != nil {
		return nil, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "saml: invalid email").WithAdditional("The nameID assertion is used to retrieve the email address, please check your IDP configuration and try again.")
	}

	name := ""
	if nameAttribute := samlConfig.AttributeMapping.Name; nameAttribute != "" {
		if val := assertionInfo.Values.Get(nameAttribute); val != "" {
			name = val
		}
	}

	var groups []string
	if groupAttribute := samlConfig.AttributeMapping.Groups; groupAttribute != "" {
		groups = assertionInfo.Values.GetAll(groupAttribute)
	}

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Send time as RFC3339Nano (e.g. 2024-01-01T00:00:00Z) or as epoch seconds/nanoseconds
  2. Validate the timestamp client-side with the same three strategies (ParseFloat, integer epoch, time.Parse(time.RFC3339Nano)) before issuing the request
  3. If you need Prometheus-style relative times like '5m', compute and send the absolute epoch instead

Example fix

# before
curl '.../api/v1/query?time=2024-01-01 00:00:00'

# after
curl '.../api/v1/query?time=2024-01-01T00:00:00Z'
Defensive patterns

Strategy: validation

Validate before calling

func validMetricsTime(s string) bool {
	if _, err := strconv.ParseFloat(s, 64); err == nil { return true }
	if _, err := time.Parse(time.RFC3339Nano, s); err == nil { return true }
	return false
}
if !validMetricsTime(timeStr) { /* fix before sending */ }

Type guard

null

Try / catch

// client side (Go)
if _, err := time.Parse(time.RFC3339Nano, s); err != nil {
	s = time.Now().UTC().Format(time.RFC3339Nano)
}

Prevention

When it happens

Trigger: Calling /api/v1/query or /api/v1/query_range (or parseInstantQueryMetricsRequest/parseQueryRangeRequest) with a time value that is neither a plain float/integer epoch nor RFC3339Nano — e.g. '2024-01-01 00:00' (space instead of T), '1h-ago', an empty-derived default, or a locale-formatted date.

Common situations: Frontends sending moment.js date-fns formatted strings instead of ISO-8601 with 'T'; shell scripts passing relative durations expecting Prometheus syntax; timezone offsets written as '+05:30' with a space separator; migrations from the Prometheus API which allows more formats.

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/d6e942f5ab81806d. Report an issue: GitHub.